home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Programming / QuakeTools / src / libqbuild / qcc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-11  |  86.2 KB  |  3,808 lines

  1. #define    LIBQBUILD_CORE
  2. #include "../include/libqbuild.h"
  3. #include "qcc.h"
  4.  
  5. //===========================================================================
  6.  
  7. char sourcedir[NAMELEN_PATH];                // 256
  8. char destfile[NAMELEN_PATH];                // 256
  9.  
  10. float *pr_globals = 0;        //[MAX_REGS];        // 65536
  11. int numpr_globals;                    // 4
  12.  
  13. char *strings = 0;        //[MAX_STRINGS];    // 500000
  14. int strofs;                        // 4
  15.  
  16. dstatement_t *statements = 0;    //[MAX_STATEMENTS];    // 65536 * 8 = 524288
  17. int numstatements;                    // 4
  18. int *statement_linenums = 0;    //[MAX_STATEMENTS];    // 65536 * 4 = 262144
  19.  
  20. dfunction_t *functions = 0;    //[MAX_FUNCTIONS];    // 8192 * (28 + 8) = 294912
  21. int numfunctions;                    // 4
  22.  
  23. ddef_t *globals = 0;        //[MAX_GLOBALS];    // 16384 * 10 = 163840
  24. int numglobaldefs;                    // 4
  25.  
  26. ddef_t *fields = 0;        //[MAX_FIELDS];        // 1024 * 10 = 10240
  27. int numfielddefs;                    // 4
  28.  
  29. char precache_sounds[MAX_SOUNDS][MAX_DATA_PATH];        // 1024 * 64 = 65536
  30. int precache_sounds_block[MAX_SOUNDS];            // 1024 * 4 = 4096
  31. int numsounds;                        // 4
  32.  
  33. char precache_models[MAX_MODELS][MAX_DATA_PATH];        // 1024 * 64 = 65536
  34. int precache_models_block[MAX_SOUNDS];            // 1024 * 4 = 4096
  35. int nummodels;                        // 4
  36.  
  37. char precache_files[MAX_FILES][MAX_DATA_PATH];        // 1024 * 64 = 65536
  38. int precache_files_block[MAX_SOUNDS];            // 1024 * 4 = 4096
  39. int numfiles;                        // 4
  40.  
  41. //===========================================================================
  42.  
  43. int pr_source_line;
  44.  
  45. char *pr_file_p;
  46. // start of current source line
  47. char *pr_line_start;
  48.  
  49. int pr_bracelevel;
  50.  
  51. char pr_token[2048];
  52. token_type_t pr_token_type;
  53. type_t *pr_immediate_type;
  54. eval_t pr_immediate;
  55.  
  56. char pr_immediate_string[2048];
  57.  
  58. int pr_error_count;
  59.  
  60. char *pr_punctuation[] =
  61. // longer symbols must be before a shorter partial match
  62. {"&&", "||", "<=", ">=", "==", "!=", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", ".", "<", ">", "#", "&", "|", NULL};
  63.  
  64. extern def_t def_void;
  65. extern def_t def_string;
  66. extern def_t def_float;
  67. extern def_t def_vector;
  68. extern def_t def_entity;
  69. extern def_t def_field;
  70. extern def_t def_function;
  71. extern def_t def_pointer;
  72.  
  73. // simple types.  function types are dynamically allocated
  74. type_t type_void =
  75. {ev_void, &def_void};
  76. type_t type_string =
  77. {ev_string, &def_string};
  78. type_t type_float =
  79. {ev_float, &def_float};
  80. type_t type_vector =
  81. {ev_vector, &def_vector};
  82. type_t type_entity =
  83. {ev_entity, &def_entity};
  84. type_t type_field =
  85. {ev_field, &def_field};
  86. type_t type_function =
  87. {ev_function, &def_function, NULL, &type_void};
  88.  
  89. // type_function is a void() function used for state defs
  90. type_t type_pointer =
  91. {ev_pointer, &def_pointer};
  92.  
  93. type_t type_floatfield =
  94. {ev_field, &def_field, NULL, &type_float};
  95.  
  96. int type_size[8] =
  97. {1, 1, 1, 3, 1, 1, 1, 1};
  98.  
  99. def_t def_void =
  100. {&type_void, "temp"};
  101. def_t def_string =
  102. {&type_string, "temp"};
  103. def_t def_float =
  104. {&type_float, "temp"};
  105. def_t def_vector =
  106. {&type_vector, "temp"};
  107. def_t def_entity =
  108. {&type_entity, "temp"};
  109. def_t def_field =
  110. {&type_field, "temp"};
  111. def_t def_function =
  112. {&type_function, "temp"};
  113. def_t def_pointer =
  114. {&type_pointer, "temp"};
  115.  
  116. def_t def_ret, def_parms[MAX_PARMS];
  117.  
  118. def_t *def_for_type[8] =
  119. {&def_void, &def_string, &def_float, &def_vector, &def_entity, &def_field, &def_function, &def_pointer};
  120.  
  121. //===========================================================================
  122.  
  123. pr_info_t pr;
  124. def_t *pr_global_defs[MAX_REGS];
  125.                            // to find def for a global variable
  126.  
  127. int pr_edict_size;
  128.  
  129. char pr_parm_names[MAX_PARMS][MAX_NAME];
  130.  
  131. //========================================
  132.  
  133. // the function being parsed, or NULL
  134. def_t *pr_scope;
  135.  
  136. bool pr_dumpasm;
  137. // filename for function definition
  138. string_t s_file;
  139.  
  140. // for tracking local variables vs temps
  141. int locals_end;
  142.  
  143. // longjump with this on parse error
  144. jmp_buf pr_parse_abort;
  145.  
  146. char pr_framemacros[MAX_FRAMES][16];
  147. int pr_nummacros;
  148.  
  149. //========================================
  150.  
  151. opcode_t pr_opcodes[] =
  152. {
  153.   {"<DONE>", "DONE", -1, FALSE, &def_entity, &def_field, &def_void},
  154.  
  155.   {"*", "MUL_F", 2, FALSE, &def_float, &def_float, &def_float},
  156.   {"*", "MUL_V", 2, FALSE, &def_vector, &def_vector, &def_float},
  157.   {"*", "MUL_FV", 2, FALSE, &def_float, &def_vector, &def_vector},
  158.   {"*", "MUL_VF", 2, FALSE, &def_vector, &def_float, &def_vector},
  159.  
  160.   {"/", "DIV", 2, FALSE, &def_float, &def_float, &def_float},
  161.  
  162.   {"+", "ADD_F", 3, FALSE, &def_float, &def_float, &def_float},
  163.   {"+", "ADD_V", 3, FALSE, &def_vector, &def_vector, &def_vector},
  164.  
  165.   {"-", "SUB_F", 3, FALSE, &def_float, &def_float, &def_float},
  166.   {"-", "SUB_V", 3, FALSE, &def_vector, &def_vector, &def_vector},
  167.  
  168.   {"==", "EQ_F", 4, FALSE, &def_float, &def_float, &def_float},
  169.   {"==", "EQ_V", 4, FALSE, &def_vector, &def_vector, &def_float},
  170.   {"==", "EQ_S", 4, FALSE, &def_string, &def_string, &def_float},
  171.   {"==", "EQ_E", 4, FALSE, &def_entity, &def_entity, &def_float},
  172.   {"==", "EQ_FNC", 4, FALSE, &def_function, &def_function, &def_float},
  173.  
  174.   {"!=", "NE_F", 4, FALSE, &def_float, &def_float, &def_float},
  175.   {"!=", "NE_V", 4, FALSE, &def_vector, &def_vector, &def_float},
  176.   {"!=", "NE_S", 4, FALSE, &def_string, &def_string, &def_float},
  177.   {"!=", "NE_E", 4, FALSE, &def_entity, &def_entity, &def_float},
  178.   {"!=", "NE_FNC", 4, FALSE, &def_function, &def_function, &def_float},
  179.  
  180.   {"<=", "LE", 4, FALSE, &def_float, &def_float, &def_float},
  181.   {">=", "GE", 4, FALSE, &def_float, &def_float, &def_float},
  182.   {"<", "LT", 4, FALSE, &def_float, &def_float, &def_float},
  183.   {">", "GT", 4, FALSE, &def_float, &def_float, &def_float},
  184.  
  185.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_float},
  186.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_vector},
  187.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_string},
  188.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_entity},
  189.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_field},
  190.   {".", "INDIRECT", 1, FALSE, &def_entity, &def_field, &def_function},
  191.  
  192.   {".", "ADDRESS", 1, FALSE, &def_entity, &def_field, &def_pointer},
  193.  
  194.   {"=", "STORE_F", 5, TRUE, &def_float, &def_float, &def_float},
  195.   {"=", "STORE_V", 5, TRUE, &def_vector, &def_vector, &def_vector},
  196.   {"=", "STORE_S", 5, TRUE, &def_string, &def_string, &def_string},
  197.   {"=", "STORE_ENT", 5, TRUE, &def_entity, &def_entity, &def_entity},
  198.   {"=", "STORE_FLD", 5, TRUE, &def_field, &def_field, &def_field},
  199.   {"=", "STORE_FNC", 5, TRUE, &def_function, &def_function, &def_function},
  200.  
  201.   {"=", "STOREP_F", 5, TRUE, &def_pointer, &def_float, &def_float},
  202.   {"=", "STOREP_V", 5, TRUE, &def_pointer, &def_vector, &def_vector},
  203.   {"=", "STOREP_S", 5, TRUE, &def_pointer, &def_string, &def_string},
  204.   {"=", "STOREP_ENT", 5, TRUE, &def_pointer, &def_entity, &def_entity},
  205.   {"=", "STOREP_FLD", 5, TRUE, &def_pointer, &def_field, &def_field},
  206.   {"=", "STOREP_FNC", 5, TRUE, &def_pointer, &def_function, &def_function},
  207.  
  208.   {"<RETURN>", "RETURN", -1, FALSE, &def_void, &def_void, &def_void},
  209.  
  210.   {"!", "NOT_F", -1, FALSE, &def_float, &def_void, &def_float},
  211.   {"!", "NOT_V", -1, FALSE, &def_vector, &def_void, &def_float},
  212.   {"!", "NOT_S", -1, FALSE, &def_vector, &def_void, &def_float},
  213.   {"!", "NOT_ENT", -1, FALSE, &def_entity, &def_void, &def_float},
  214.   {"!", "NOT_FNC", -1, FALSE, &def_function, &def_void, &def_float},
  215.  
  216.   {"<IF>", "IF", -1, FALSE, &def_float, &def_float, &def_void},
  217.   {"<IFNOT>", "IFNOT", -1, FALSE, &def_float, &def_float, &def_void},
  218.  
  219. // calls returns REG_RETURN
  220.   {"<CALL0>", "CALL0", -1, FALSE, &def_function, &def_void, &def_void},
  221.   {"<CALL1>", "CALL1", -1, FALSE, &def_function, &def_void, &def_void},
  222.   {"<CALL2>", "CALL2", -1, FALSE, &def_function, &def_void, &def_void},
  223.   {"<CALL3>", "CALL3", -1, FALSE, &def_function, &def_void, &def_void},
  224.   {"<CALL4>", "CALL4", -1, FALSE, &def_function, &def_void, &def_void},
  225.   {"<CALL5>", "CALL5", -1, FALSE, &def_function, &def_void, &def_void},
  226.   {"<CALL6>", "CALL6", -1, FALSE, &def_function, &def_void, &def_void},
  227.   {"<CALL7>", "CALL7", -1, FALSE, &def_function, &def_void, &def_void},
  228.   {"<CALL8>", "CALL8", -1, FALSE, &def_function, &def_void, &def_void},
  229.  
  230.   {"<STATE>", "STATE", -1, FALSE, &def_float, &def_float, &def_void},
  231.  
  232.   {"<GOTO>", "GOTO", -1, FALSE, &def_float, &def_void, &def_void},
  233.  
  234.   {"&&", "AND", 6, FALSE, &def_float, &def_float, &def_float},
  235.   {"||", "OR", 6, FALSE, &def_float, &def_float, &def_float},
  236.  
  237.   {"&", "BITAND", 2, FALSE, &def_float, &def_float, &def_float},
  238.   {"|", "BITOR", 2, FALSE, &def_float, &def_float, &def_float},
  239.  
  240.   {NULL}
  241. };
  242.  
  243. def_t *PR_Expression(register int priority);
  244.  
  245. def_t junkdef;
  246.  
  247. //===========================================================================
  248. //qcc
  249. //===========================================================================
  250.  
  251. // CopyString returns an offset from the string heap
  252. int CopyString(register char *str)
  253. {
  254.   int old;
  255.  
  256.   old = strofs;
  257.   strcpy(strings + strofs, str);
  258.   strofs += strlen(str) + 1;
  259.   return old;
  260. }
  261.  
  262. void PrintStrings(void)
  263. {
  264.   int i, l, j;
  265.  
  266.   for (i = 0; i < strofs; i += l) {
  267.     l = strlen(strings + i) + 1;
  268.     mprintf("%5i : ", i);
  269.     for (j = 0; j < l; j++) {
  270.       if (strings[i + j] == '\n') {
  271.     putchar('\\');
  272.     putchar('n');
  273.       }
  274.       else
  275.     putchar(strings[i + j]);
  276.     }
  277.     mprintf("\n");
  278.   }
  279. }
  280.  
  281. void PrintFunctions(void)
  282. {
  283.   int i, j;
  284.   dfunction_t *d;
  285.  
  286.   for (i = 0; i < numfunctions; i++) {
  287.     d = &functions[i];
  288.     mprintf("%s : %s : %i %i (", strings + d->s_file, strings + d->s_name, d->first_statement, d->parm_start);
  289.     for (j = 0; j < d->numparms; j++)
  290.       mprintf("%i ", d->parm_size[j]);
  291.     mprintf(")\n");
  292.   }
  293. }
  294.  
  295. void PrintFields(void)
  296. {
  297.   int i;
  298.   ddef_t *d;
  299.  
  300.   for (i = 0; i < numfielddefs; i++) {
  301.     d = &fields[i];
  302.     mprintf("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name);
  303.   }
  304. }
  305.  
  306. void PrintGlobals(void)
  307. {
  308.   int i;
  309.   ddef_t *d;
  310.  
  311.   for (i = 0; i < numglobaldefs; i++) {
  312.     d = &globals[i];
  313.     mprintf("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name);
  314.   }
  315. }
  316.  
  317. //===========================================================================
  318.  
  319. void PrecacheSound(register def_t * e, register int ch)
  320. {
  321.   char *n;
  322.   int i;
  323.  
  324.   if (!e->ofs)
  325.     return;
  326.   n = G_STRING(e->ofs);
  327.   for (i = 0; i < numsounds; i++)
  328.     if (!strcmp(n, precache_sounds[i]))
  329.       return;
  330.   if (numsounds == MAX_SOUNDS)
  331.     eprintf("PrecacheSound: numsounds == MAX_SOUNDS");
  332.   strcpy(precache_sounds[i], n);
  333.   if (ch >= '1' && ch <= '9')
  334.     precache_sounds_block[i] = ch - '0';
  335.   else
  336.     precache_sounds_block[i] = 1;
  337.   numsounds++;
  338. }
  339.  
  340. void PrecacheModel(register def_t * e, register int ch)
  341. {
  342.   char *n;
  343.   int i;
  344.  
  345.   if (!e->ofs)
  346.     return;
  347.   n = G_STRING(e->ofs);
  348.   for (i = 0; i < nummodels; i++)
  349.     if (!strcmp(n, precache_models[i]))
  350.       return;
  351.   if (numsounds == MAX_SOUNDS)
  352.     eprintf("PrecacheModels: numsounds == MAX_SOUNDS");
  353.   strcpy(precache_models[i], n);
  354.   if (ch >= '1' && ch <= '9')
  355.     precache_models_block[i] = ch - '0';
  356.   else
  357.     precache_models_block[i] = 1;
  358.   nummodels++;
  359. }
  360.  
  361. void PrecacheFile(register def_t * e, register int ch)
  362. {
  363.   char *n;
  364.   int i;
  365.  
  366.   if (!e->ofs)
  367.     return;
  368.   n = G_STRING(e->ofs);
  369.   for (i = 0; i < numfiles; i++)
  370.     if (!strcmp(n, precache_files[i]))
  371.       return;
  372.   if (numfiles == MAX_FILES)
  373.     eprintf("PrecacheFile: numfiles == MAX_FILES");
  374.   strcpy(precache_files[i], n);
  375.   if (ch >= '1' && ch <= '9')
  376.     precache_files_block[i] = ch - '0';
  377.   else
  378.     precache_files_block[i] = 1;
  379.   numfiles++;
  380. }
  381.  
  382. //===========================================================================
  383.  
  384. bool ExitData(void)
  385. {
  386.   kfree();
  387.  
  388.   return FALSE;
  389. }
  390.  
  391. bool InitData(void)
  392. {
  393.   int i;
  394.  
  395.   if(!(pr_globals = (float *)kmalloc(MAX_REGS * sizeof(float))))
  396.     return ExitData();
  397.   if(!(strings = (char *)kmalloc(MAX_STRINGS * sizeof(char))))
  398.     return ExitData();
  399.   if(!(statements = (dstatement_t *)kmalloc(MAX_STATEMENTS * sizeof(dstatement_t))))
  400.     return ExitData();
  401.   if(!(statement_linenums = (int *)kmalloc(MAX_STATEMENTS * sizeof(int))))
  402.     return ExitData();
  403.   if(!(functions = (dfunction_t *)kmalloc(MAX_FUNCTIONS * sizeof(dfunction_t))))
  404.     return ExitData();
  405.   if(!(globals = (ddef_t *)kmalloc(MAX_GLOBALS * sizeof(ddef_t))))
  406.     return ExitData();
  407.   if(!(fields = (ddef_t *)kmalloc(MAX_FIELDS * sizeof(ddef_t))))
  408.     return ExitData();
  409.  
  410.   numstatements = 1;
  411.   strofs = 1;
  412.   numfunctions = 1;
  413.   numglobaldefs = 1;
  414.   numfielddefs = 1;
  415.  
  416.   def_ret.ofs = OFS_RETURN;
  417.   for (i = 0; i < MAX_PARMS; i++)
  418.     def_parms[i].ofs = OFS_PARM0 + 3 * i;
  419.   
  420.   return TRUE;
  421. }
  422.  
  423. void WriteData(register int crc)
  424. {
  425.   def_t *def;
  426.   ddef_t *dd;
  427.   dprograms_t progs;
  428.   FILE *h;
  429.   int i;
  430.  
  431.   for (def = pr.def_head.next; def; def = def->next) {
  432.     if (def->type->type == ev_function) {
  433.       /*
  434.        * df = &functions[numfunctions];
  435.        * numfunctions++;
  436.        */
  437.     }
  438.     else if (def->type->type == ev_field) {
  439.       dd = &fields[numfielddefs];
  440.       numfielddefs++;
  441.       dd->type = def->type->aux_type->type;
  442.       dd->s_name = CopyString(def->name);
  443.       dd->ofs = G_INT(def->ofs);
  444.     }
  445.     dd = &globals[numglobaldefs];
  446.     numglobaldefs++;
  447.     dd->type = def->type->type;
  448.     if (!def->initialized
  449.     && def->type->type != ev_function
  450.     && def->type->type != ev_field
  451.     && def->scope == NULL)
  452.       dd->type |= DEF_SAVEGLOBGAL;
  453.     dd->s_name = CopyString(def->name);
  454.     dd->ofs = def->ofs;
  455.   }
  456.  
  457.   /*
  458.    * PrintStrings ();
  459.    * PrintFunctions ();
  460.    * PrintFields ();
  461.    * PrintGlobals ();
  462.    */
  463.   strofs = (strofs + 3) & ~3;
  464.  
  465.   mprintf("%6i strofs\n", strofs);
  466.   mprintf("%6i numstatements\n", numstatements);
  467.   mprintf("%6i numfunctions\n", numfunctions);
  468.   mprintf("%6i numglobaldefs\n", numglobaldefs);
  469.   mprintf("%6i numfielddefs\n", numfielddefs);
  470.   mprintf("%6i numpr_globals\n", numpr_globals);
  471.  
  472.   if((h = fopen(destfile, READWRITE_BINARY_OLD))) {
  473.     fwrite(&progs, 1, sizeof(progs), h);
  474.  
  475.     progs.ofs_strings = ftell(h);
  476.     progs.numstrings = strofs;
  477.     fwrite(strings, 1, strofs, h);
  478.  
  479.     progs.ofs_statements = ftell(h);
  480.     progs.numstatements = numstatements;
  481.     for (i = 0; i < numstatements; i++) {
  482.       statements[i].op = LittleShort(statements[i].op);
  483.       statements[i].a = LittleShort(statements[i].a);
  484.       statements[i].b = LittleShort(statements[i].b);
  485.       statements[i].c = LittleShort(statements[i].c);
  486.     }
  487.     fwrite(statements, 1, numstatements * sizeof(dstatement_t), h);
  488.  
  489.     progs.ofs_functions = ftell(h);
  490.     progs.numfunctions = numfunctions;
  491.     for (i = 0; i < numfunctions; i++) {
  492.       functions[i].first_statement = LittleLong(functions[i].first_statement);
  493.       functions[i].parm_start = LittleLong(functions[i].parm_start);
  494.       functions[i].s_name = LittleLong(functions[i].s_name);
  495.       functions[i].s_file = LittleLong(functions[i].s_file);
  496.       functions[i].numparms = LittleLong(functions[i].numparms);
  497.       functions[i].locals = LittleLong(functions[i].locals);
  498.     }
  499.     fwrite(functions, 1, numfunctions * sizeof(dfunction_t), h);
  500.  
  501.     progs.ofs_globaldefs = ftell(h);
  502.     progs.numglobaldefs = numglobaldefs;
  503.     for (i = 0; i < numglobaldefs; i++) {
  504.       globals[i].type = LittleShort(globals[i].type);
  505.       globals[i].ofs = LittleShort(globals[i].ofs);
  506.       globals[i].s_name = LittleLong(globals[i].s_name);
  507.     }
  508.     fwrite(globals, 1, numglobaldefs * sizeof(ddef_t), h);
  509.  
  510.     progs.ofs_fielddefs = ftell(h);
  511.     progs.numfielddefs = numfielddefs;
  512.     for (i = 0; i < numfielddefs; i++) {
  513.       fields[i].type = LittleShort(fields[i].type);
  514.       fields[i].ofs = LittleShort(fields[i].ofs);
  515.       fields[i].s_name = LittleLong(fields[i].s_name);
  516.     }
  517.     fwrite(fields, 1, numfielddefs * sizeof(ddef_t), h);
  518.  
  519.     progs.ofs_globals = ftell(h);
  520.     progs.numglobals = numpr_globals;
  521.     for (i = 0; i < numpr_globals; i++)
  522.       ((int *)pr_globals)[i] = LittleLong(((int *)pr_globals)[i]);
  523.     fwrite(pr_globals, 1, numpr_globals * 4, h);
  524.  
  525.     mprintf("%6i TOTAL SIZE\n", (int)ftell(h));
  526.  
  527.     progs.entityfields = pr.size_fields;
  528.     progs.version = PROG_VERSION;
  529.     progs.crc = crc;
  530.  
  531.     // unsigned char swap the header and write it out
  532.     for (i = 0; i < sizeof(progs) / 4; i++)
  533.       ((int *)&progs)[i] = LittleLong(((int *)&progs)[i]);
  534.     fseek(h, 0, SEEK_SET);
  535.     fwrite(&progs, 1, sizeof(progs), h);
  536.  
  537.     fclose(h);
  538.   }
  539. }
  540.  
  541. bool ReadData (register FILE *srcFile) {
  542.   dprograms_t    progs;
  543.   int i;
  544.   bool retval = FALSE;
  545.  
  546.   while(1) {
  547.     if(fread (&progs, 1, sizeof(progs), srcFile) != sizeof(progs))
  548.       break;
  549.  
  550.     fseek (srcFile, LittleLong(progs.ofs_strings), SEEK_SET);
  551.     strofs = LittleLong(progs.numstrings);
  552.     if(!(strings = (char *)kmalloc(strofs)))
  553.       break;
  554.     if(fread (strings, 1, strofs, srcFile) != strofs)
  555.       break;
  556.     
  557.     fseek (srcFile, LittleLong(progs.ofs_statements), SEEK_SET);
  558.     numstatements = LittleLong(progs.numstatements);
  559.     if(!(statements = (dstatement_t *)kmalloc(numstatements * sizeof(dstatement_t))))
  560.       break;
  561.     if(!(statement_linenums = (int *)kmalloc(numstatements * sizeof(int))))
  562.       break;
  563.     if(fread (statements, 1, numstatements * sizeof(dstatement_t), srcFile) != (numstatements * sizeof(dstatement_t)))
  564.       break;
  565.     for (i = 0; i < numstatements; i++) {
  566.       statements[i].op = LittleShort(statements[i].op);
  567.       statements[i].a = LittleShort(statements[i].a);
  568.       statements[i].b = LittleShort(statements[i].b);
  569.       statements[i].c = LittleShort(statements[i].c);
  570.     }
  571.  
  572.     fseek (srcFile, LittleLong(progs.ofs_functions), SEEK_SET);
  573.     numfunctions = LittleLong(progs.numfunctions); 
  574.     if(!(functions = (dfunction_t *)kmalloc(numfunctions * sizeof(dfunction_t))))
  575.       break;
  576.     if(fread (functions, 1, numfunctions * sizeof(dfunction_t), srcFile) != (numfunctions * sizeof(dfunction_t)))
  577.       break;
  578.     for (i = 0; i < numfunctions; i++) {
  579.       functions[i].first_statement = LittleLong(functions[i].first_statement);
  580.       functions[i].parm_start = LittleLong(functions[i].parm_start);
  581.       functions[i].locals = LittleLong(functions[i].locals);
  582.       functions[i].s_name = LittleLong(functions[i].s_name);
  583.       functions[i].s_file = LittleLong(functions[i].s_file);
  584.       functions[i].numparms = LittleLong(functions[i].numparms);
  585.     }
  586.  
  587.     fseek (srcFile, LittleLong(progs.ofs_globaldefs), SEEK_SET);
  588.     numglobaldefs = LittleLong(progs.numglobaldefs);
  589.     if(!(globals = (ddef_t *)kmalloc(numglobaldefs * sizeof(ddef_t))))
  590.       break;
  591.     if(fread (globals, 1, numglobaldefs * sizeof(ddef_t), srcFile) != (numglobaldefs * sizeof(ddef_t)))
  592.       break;
  593.     for (i = 0; i < numglobaldefs; i++) {
  594.       globals[i].type = LittleShort(globals[i].type);
  595.       globals[i].ofs = LittleShort(globals[i].ofs);
  596.       globals[i].s_name = LittleLong(globals[i].s_name);
  597.     }
  598.  
  599.     fseek (srcFile, LittleLong(progs.ofs_fielddefs), SEEK_SET);
  600.     numfielddefs = LittleLong(progs.numfielddefs);  
  601.     if(!(fields = (ddef_t *)kmalloc(numfielddefs * sizeof(ddef_t))))
  602.       break;
  603.     if(fread (fields, 1, numfielddefs*sizeof(ddef_t), srcFile) != (numfielddefs*sizeof(ddef_t)))
  604.       break;
  605.     for (i = 0; i < numfielddefs; i++) {
  606.       fields[i].type = LittleShort(fields[i].type);
  607.       fields[i].ofs = LittleShort(fields[i].ofs);
  608.       fields[i].s_name = LittleLong(fields[i].s_name);
  609.     }
  610.  
  611.     fseek (srcFile, LittleLong(progs.ofs_globals), SEEK_SET);
  612.     numpr_globals = LittleLong(progs.numglobals);
  613.     if(!(pr_globals = (float *)kmalloc(numpr_globals * sizeof(float))))
  614.       break;
  615.     if(fread (pr_globals, 1, numpr_globals*4, srcFile) != (numpr_globals*4))
  616.       break;
  617.     for (i = 0; i < numpr_globals; i++)
  618.       ((int *)pr_globals)[i] = LittleLong(((int *)pr_globals)[i]);
  619.  
  620.     printf ("total size is %6i\n", (int)ftell(srcFile));
  621.     printf ("version code is %i\n",LittleLong(progs.version));
  622.     printf ("crc is %i\n",LittleLong(progs.crc));
  623.     printf ("%6i strofs\n", strofs);
  624.     printf ("%6i numstatements\n", numstatements);
  625.     printf ("%6i numfunctions\n", numfunctions);
  626.     printf ("%6i numglobaldefs\n", numglobaldefs);
  627.     printf ("%6i numfielddefs\n", numfielddefs);
  628.     printf ("%6i numpr_globals\n", numpr_globals);
  629.     printf ("--------------------------\n");
  630.     retval = TRUE;
  631.     break;
  632.   }
  633.     
  634.   return retval;
  635. }
  636.  
  637. bool ShowData (register FILE *srcFile) {
  638.   dprograms_t    progs;
  639.  
  640.   if(fread(&progs, 1, sizeof(progs), srcFile) == sizeof(progs)) {
  641.     strofs = LittleLong(progs.numstrings);
  642.     numstatements = LittleLong(progs.numstatements);
  643.     numfunctions = LittleLong(progs.numfunctions); 
  644.     numglobaldefs = LittleLong(progs.numglobaldefs);
  645.     numfielddefs = LittleLong(progs.numfielddefs);  
  646.     numpr_globals = LittleLong(progs.numglobals);
  647.  
  648.     fseek (srcFile, 0, SEEK_END);
  649.     printf ("total size is %6i\n", (int)ftell(srcFile));
  650.     printf ("version code is %i\n", LittleLong(progs.version));
  651.     printf ("crc is %i\n", LittleLong(progs.crc));
  652.     printf ("%6i strofs\n", strofs);
  653.     printf ("%6i numstatements\n", numstatements);
  654.     printf ("%6i numfunctions\n", numfunctions);
  655.     printf ("%6i numglobaldefs\n", numglobaldefs);
  656.     printf ("%6i numfielddefs\n", numfielddefs);
  657.     printf ("%6i numpr_globals\n", numpr_globals);
  658.     printf ("--------------------------\n");
  659.     return TRUE;
  660.   }
  661.   else
  662.     return FALSE;
  663. }
  664.  
  665. /*
  666.  * 
  667.  * ============
  668.  * WriteFiles
  669.  * 
  670.  * Generates files.dat, which contains all of the
  671.  * data files actually used by the game, to be
  672.  * processed by qfiles.exe
  673.  * ============
  674.  */
  675. void WriteFiles(void)
  676. {
  677.   FILE *f;
  678.   int i;
  679.   char filename[NAMELEN_PATH];
  680.  
  681.   sprintf(filename, "%sfiles.dat", sourcedir);
  682.   f = fopen(filename, "w");
  683.   if (!f)
  684.     eprintf("Couldn't open %s", filename);
  685.   else {
  686.     fprintf(f, "%i\n", numsounds);
  687.     for (i = 0; i < numsounds; i++)
  688.       fprintf(f, "%i %s\n", precache_sounds_block[i], precache_sounds[i]);
  689.  
  690.     fprintf(f, "%i\n", nummodels);
  691.     for (i = 0; i < nummodels; i++)
  692.       fprintf(f, "%i %s\n", precache_models_block[i], precache_models[i]);
  693.  
  694.     fprintf(f, "%i\n", numfiles);
  695.     for (i = 0; i < numfiles; i++)
  696.       fprintf(f, "%i %s\n", precache_files_block[i], precache_files[i]);
  697.  
  698.     fclose(f);
  699.   }
  700. }
  701.  
  702. //===========================================================================
  703.  
  704. /*
  705.  * ============
  706.  * PR_ParseError
  707.  * 
  708.  * Aborts the current file load
  709.  * ============
  710.  */
  711. void PR_ParseError(register char *error,...)
  712. {
  713.   va_list argptr;
  714.   char string[1024];
  715.  
  716.   va_start(argptr, error);
  717.   vsprintf(string, error, argptr);
  718.   va_end(argptr);
  719.  
  720.   mprintf("%s:%i:%s\n", strings + s_file, pr_source_line, string);
  721.  
  722.   longjmp(pr_parse_abort, 1);
  723. }
  724.  
  725. /*
  726.  * ==============
  727.  * PR_PrintNextLine
  728.  * ==============
  729.  */
  730. void PR_PrintNextLine(void)
  731. {
  732.   char *t;
  733.  
  734.   mprintf("%3i:", pr_source_line);
  735.   for (t = pr_line_start; *t && *t != '\n'; t++)
  736.     mprintf("%c", *t);
  737.   mprintf("\n");
  738. }
  739.  
  740. /*
  741.  * ==============
  742.  * PR_NewLine
  743.  * 
  744.  * Call at start of file and when *pr_file_p == '\n'
  745.  * ==============
  746.  */
  747. void PR_NewLine(void)
  748. {
  749.   bool m;
  750.  
  751.   if (*pr_file_p == '\n') {
  752.     pr_file_p++;
  753.     m = TRUE;
  754.   }
  755.   else
  756.     m = FALSE;
  757.  
  758.   pr_source_line++;
  759.   pr_line_start = pr_file_p;
  760.  
  761.   /*
  762.    * if (pr_dumpasm)
  763.    * PR_PrintNextLine ();
  764.    */
  765.   if (m)
  766.     pr_file_p--;
  767. }
  768.  
  769. /*
  770.  * ==============
  771.  * PR_LexString
  772.  * 
  773.  * Parses a quoted string
  774.  * ==============
  775.  */
  776. void PR_LexString(void)
  777. {
  778.   int c;
  779.   int len;
  780.  
  781.   len = 0;
  782.   pr_file_p++;
  783.   do {
  784.     c = *pr_file_p++;
  785.     if (!c)
  786.       PR_ParseError("EOF inside quote");
  787.     if (c == '\n')
  788.       PR_ParseError("newline inside quote");
  789.     if (c == '\\') {                                   // escape char
  790.       c = *pr_file_p++;
  791.       if (!c)
  792.     PR_ParseError("EOF inside quote");
  793.       if (c == 'n')
  794.     c = '\n';
  795.       else if (c == '"')
  796.     c = '"';
  797.       else
  798.     PR_ParseError("Unknown escape char");
  799.     }
  800.     else if (c == '\"') {
  801.       pr_token[len] = 0;
  802.       pr_token_type = tt_immediate;
  803.       pr_immediate_type = &type_string;
  804.       strcpy(pr_immediate_string, pr_token);
  805.       return;
  806.     }
  807.     pr_token[len] = c;
  808.     len++;
  809.   } while (1);
  810. }
  811.  
  812. /*
  813.  * ==============
  814.  * PR_LexNumber
  815.  * ==============
  816.  */
  817. float PR_LexNumber(void)
  818. {
  819.   int c;
  820.   int len;
  821.  
  822.   len = 0;
  823.   c = *pr_file_p;
  824.   do {
  825.     pr_token[len] = c;
  826.     len++;
  827.     pr_file_p++;
  828.     c = *pr_file_p;
  829.   } while ((c >= '0' && c <= '9') || c == '.');
  830.   pr_token[len] = 0;
  831.   return atof(pr_token);
  832. }
  833.  
  834. /*
  835.  * ==============
  836.  * PR_LexWhitespace
  837.  * ==============
  838.  */
  839. void PR_LexWhitespace(void)
  840. {
  841.   int c;
  842.  
  843.   while (1) {
  844.     // skip whitespace
  845.     while ((c = *pr_file_p) <= ' ') {
  846.       if (c == '\n')
  847.     PR_NewLine();
  848.       if (c == 0)
  849.     return;                                       // end of file
  850.  
  851.       pr_file_p++;
  852.     }
  853.  
  854.     // skip // comments
  855.     if (c == '/' && pr_file_p[1] == '/') {
  856.       while (*pr_file_p && *pr_file_p != '\n')
  857.     pr_file_p++;
  858.       PR_NewLine();
  859.       pr_file_p++;
  860.       continue;
  861.     }
  862.  
  863.     // skip /* */ comments
  864.     if (c == '/' && pr_file_p[1] == '*') {
  865.       do {
  866.     pr_file_p++;
  867.     if (pr_file_p[0] == '\n')
  868.       PR_NewLine();
  869.     if (pr_file_p[1] == 0)
  870.       return;
  871.       } while (pr_file_p[-1] != '*' || pr_file_p[0] != '/');
  872.       pr_file_p++;
  873.       continue;
  874.     }
  875.     break;                                       // a real character has been found
  876.  
  877.   }
  878. }
  879.  
  880. /*
  881.  * ==============
  882.  * PR_LexVector
  883.  * 
  884.  * Parses a single quoted vector
  885.  * ==============
  886.  */
  887. void PR_LexVector(void)
  888. {
  889.   int i;
  890.  
  891.   pr_file_p++;
  892.   pr_token_type = tt_immediate;
  893.   pr_immediate_type = &type_vector;
  894.   for (i = 0; i < 3; i++) {
  895.     pr_immediate.vector[i] = PR_LexNumber();
  896.     PR_LexWhitespace();
  897.   }
  898.   if (*pr_file_p != '\'')
  899.     PR_ParseError("Bad vector");
  900.   pr_file_p++;
  901. }
  902.  
  903. /*
  904.  * ==============
  905.  * PR_LexName
  906.  * 
  907.  * Parses an identifier
  908.  * ==============
  909.  */
  910. void PR_LexName(void)
  911. {
  912.   int c;
  913.   int len;
  914.  
  915.   len = 0;
  916.   c = *pr_file_p;
  917.   do {
  918.     pr_token[len] = c;
  919.     len++;
  920.     pr_file_p++;
  921.     c = *pr_file_p;
  922.   } while ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9'));
  923.   pr_token[len] = 0;
  924.   pr_token_type = tt_name;
  925. }
  926.  
  927. /*
  928.  * ==============
  929.  * PR_LexPunctuation
  930.  * ==============
  931.  */
  932. void PR_LexPunctuation(void)
  933. {
  934.   int i;
  935.   int len;
  936.   char *p;
  937.  
  938.   pr_token_type = tt_punct;
  939.  
  940.   for (i = 0; (p = pr_punctuation[i]) != NULL; i++) {
  941.     len = strlen(p);
  942.     if (!strncmp(p, pr_file_p, len)) {
  943.       strcpy(pr_token, p);
  944.       if (p[0] == '{')
  945.     pr_bracelevel++;
  946.       else if (p[0] == '}')
  947.     pr_bracelevel--;
  948.       pr_file_p += len;
  949.       return;
  950.     }
  951.   }
  952.  
  953.   PR_ParseError("Unknown punctuation");
  954. }
  955.  
  956. void PR_ClearGrabMacros(void)
  957. {
  958.   pr_nummacros = 0;
  959. }
  960.  
  961. void PR_FindMacro(void)
  962. {
  963.   int i;
  964.  
  965.   for (i = 0; i < pr_nummacros; i++)
  966.     if (!strcmp(pr_token, pr_framemacros[i])) {
  967.       sprintf(pr_token, "%d", i);
  968.       pr_token_type = tt_immediate;
  969.       pr_immediate_type = &type_float;
  970.       pr_immediate._float = i;
  971.       return;
  972.     }
  973.   PR_ParseError("Unknown frame macro $%s", pr_token);
  974. }
  975.  
  976. // just parses text, returning FALSE if an eol is reached
  977. bool PR_SimpleGetToken(void)
  978. {
  979.   int c;
  980.   int i;
  981.  
  982. // skip whitespace
  983.   while ((c = *pr_file_p) <= ' ') {
  984.     if (c == '\n' || c == 0)
  985.       return FALSE;
  986.     pr_file_p++;
  987.   }
  988.  
  989.   i = 0;
  990.   while ((c = *pr_file_p) > ' ' && c != ',' && c != ';') {
  991.     pr_token[i] = c;
  992.     i++;
  993.     pr_file_p++;
  994.   }
  995.   pr_token[i] = 0;
  996.   return TRUE;
  997. }
  998.  
  999. void PR_ParseFrame(void)
  1000. {
  1001.   while (PR_SimpleGetToken()) {
  1002.     strcpy(pr_framemacros[pr_nummacros], pr_token);
  1003.     pr_nummacros++;
  1004.   }
  1005. }
  1006.  
  1007. /*
  1008.  * ==============
  1009.  * PR_Lex
  1010.  * 
  1011.  * Sets pr_token, pr_token_type, and possibly pr_immediate and pr_immediate_type
  1012.  * ==============
  1013.  */
  1014. void PR_LexGrab(void);
  1015. void PR_Lex(void)
  1016. {
  1017.   int c;
  1018.  
  1019.   pr_token[0] = 0;
  1020.  
  1021.   if (!pr_file_p) {
  1022.     pr_token_type = tt_eof;
  1023.     return;
  1024.   }
  1025.  
  1026.   PR_LexWhitespace();
  1027.  
  1028.   c = *pr_file_p;
  1029.  
  1030.   if (!c) {
  1031.     pr_token_type = tt_eof;
  1032.     return;
  1033.   }
  1034.  
  1035. // handle quoted strings as a unit
  1036.   if (c == '\"') {
  1037.     PR_LexString();
  1038.     return;
  1039.   }
  1040.  
  1041. // handle quoted vectors as a unit
  1042.   if (c == '\'') {
  1043.     PR_LexVector();
  1044.     return;
  1045.   }
  1046.  
  1047. // if the first character is a valid identifier, parse until a non-id
  1048.   // character is reached
  1049.   if ((c >= '0' && c <= '9') || (c == '-' && pr_file_p[1] >= '0' && pr_file_p[1] <= '9')) {
  1050.     pr_token_type = tt_immediate;
  1051.     pr_immediate_type = &type_float;
  1052.     pr_immediate._float = PR_LexNumber();
  1053.     return;
  1054.   }
  1055.  
  1056.   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') {
  1057.     PR_LexName();
  1058.     return;
  1059.   }
  1060.  
  1061.   if (c == '$') {
  1062.     PR_LexGrab();
  1063.     return;
  1064.   }
  1065.  
  1066. // parse symbol strings until a non-symbol is found
  1067.   PR_LexPunctuation();
  1068. }
  1069.  
  1070. /*
  1071.  * ==============
  1072.  * PR_LexGrab
  1073.  * 
  1074.  * Deals with counting sequence numbers and replacing frame macros
  1075.  * ==============
  1076.  */
  1077. void PR_LexGrab(void)
  1078. {
  1079.   pr_file_p++;                                       // skip the $
  1080.  
  1081.   if (!PR_SimpleGetToken())
  1082.     PR_ParseError("hanging $");
  1083.  
  1084. // check for $frame
  1085.   if (!strcmp(pr_token, "frame")) {
  1086.     PR_ParseFrame();
  1087.     PR_Lex();
  1088.   }
  1089. // ignore other known $commands
  1090.   else if (!strcmp(pr_token, "cd")
  1091.        || !strcmp(pr_token, "origin")
  1092.        || !strcmp(pr_token, "base")
  1093.        || !strcmp(pr_token, "flags")
  1094.        || !strcmp(pr_token, "scale")
  1095.        || !strcmp(pr_token, "skin")) {                       // skip to end of line
  1096.  
  1097.     while (PR_SimpleGetToken());
  1098.     PR_Lex();
  1099.   }
  1100. // look for a frame name macro
  1101.   else
  1102.     PR_FindMacro();
  1103. }
  1104.  
  1105. /*
  1106.  * =============
  1107.  * PR_Expect
  1108.  * 
  1109.  * Issues an error if the current token isn't equal to string
  1110.  * Gets the next token
  1111.  * =============
  1112.  */
  1113. void PR_Expect(register char *string)
  1114. {
  1115.   if (strcmp(string, pr_token))
  1116.     PR_ParseError("expected %s, found %s", string, pr_token);
  1117.   PR_Lex();
  1118. }
  1119.  
  1120. /*
  1121.  * =============
  1122.  * PR_Check
  1123.  * 
  1124.  * Returns TRUE and gets the next token if the current token equals string
  1125.  * Returns FALSE and does nothing otherwise
  1126.  * =============
  1127.  */
  1128. bool PR_Check(register char *string)
  1129. {
  1130.   if (strcmp(string, pr_token))
  1131.     return FALSE;
  1132.  
  1133.   PR_Lex();
  1134.   return TRUE;
  1135. }
  1136.  
  1137. /*
  1138.  * ============
  1139.  * PR_ParseName
  1140.  * 
  1141.  * Checks to see if the current token is a valid name
  1142.  * ============
  1143.  */
  1144. char *PR_ParseName(void)
  1145. {
  1146.   static char ident[MAX_NAME];
  1147.  
  1148.   if (pr_token_type != tt_name)
  1149.     PR_ParseError("not a name");
  1150.   if (strlen(pr_token) >= MAX_NAME - 1)
  1151.     PR_ParseError("name too long");
  1152.   strcpy(ident, pr_token);
  1153.   PR_Lex();
  1154.  
  1155.   return ident;
  1156. }
  1157.  
  1158. /*
  1159.  * ============
  1160.  * PR_FindType
  1161.  * 
  1162.  * Returns a preexisting complex type that matches the parm, or allocates
  1163.  * a new one and copies it out.
  1164.  * ============
  1165.  */
  1166. type_t *PR_FindType(register type_t * type)
  1167. {
  1168.   def_t *def;
  1169.   type_t *check;
  1170.   int i;
  1171.  
  1172.   for (check = pr.types; check; check = check->next) {
  1173.     if (check->type != type->type
  1174.     || check->aux_type != type->aux_type
  1175.     || check->num_parms != type->num_parms)
  1176.       continue;
  1177.  
  1178.     for (i = 0; i < type->num_parms; i++)
  1179.       if (check->parm_types[i] != type->parm_types[i])
  1180.     break;
  1181.  
  1182.     if (i == type->num_parms)
  1183.       return check;
  1184.   }
  1185.  
  1186. // allocate a new one
  1187.   check = (type_t *)kmalloc(sizeof(*check));
  1188.   *check = *type;
  1189.   check->next = pr.types;
  1190.   pr.types = check;
  1191.  
  1192. // allocate a generic def for the type, so fields can reference it
  1193.   def = (def_t *)kmalloc(sizeof(def_t));
  1194.   def->name = "COMPLEX TYPE";
  1195.   def->type = check;
  1196.   check->def = def;
  1197.   return check;
  1198. }
  1199.  
  1200. /*
  1201.  * ============
  1202.  * PR_SkipToSemicolon
  1203.  * 
  1204.  * For error recovery, also pops out of nested braces
  1205.  * ============
  1206.  */
  1207. void PR_SkipToSemicolon(void)
  1208. {
  1209.   do {
  1210.     if (!pr_bracelevel && PR_Check(";"))
  1211.       return;
  1212.     PR_Lex();
  1213.   } while (pr_token[0]);                               // eof will return a null token
  1214.  
  1215. }
  1216.  
  1217. /*
  1218.  * ============
  1219.  * PR_ParseType
  1220.  * 
  1221.  * Parses a variable type, including field and functions types
  1222.  * ============
  1223.  */
  1224. type_t *PR_ParseType(void)
  1225. {
  1226.   type_t new;
  1227.   type_t *type;
  1228.   char *name;
  1229.  
  1230.   if (PR_Check(".")) {
  1231.     memset(&new, 0, sizeof(new));
  1232.     new.type = ev_field;
  1233.     new.aux_type = PR_ParseType();
  1234.     return PR_FindType(&new);
  1235.   }
  1236.  
  1237.   if (!strcmp(pr_token, "float"))
  1238.     type = &type_float;
  1239.   else if (!strcmp(pr_token, "vector"))
  1240.     type = &type_vector;
  1241.   else if (!strcmp(pr_token, "float"))
  1242.     type = &type_float;
  1243.   else if (!strcmp(pr_token, "entity"))
  1244.     type = &type_entity;
  1245.   else if (!strcmp(pr_token, "string"))
  1246.     type = &type_string;
  1247.   else if (!strcmp(pr_token, "void"))
  1248.     type = &type_void;
  1249.   else {
  1250.     PR_ParseError("\"%s\" is not a type", pr_token);
  1251.     type = &type_float;                                   // shut up compiler warning
  1252.   }
  1253.   PR_Lex();
  1254.  
  1255.   if (!PR_Check("("))
  1256.     return type;
  1257.  
  1258. // function type
  1259.   memset(&new, 0, sizeof(new));
  1260.   new.type = ev_function;
  1261.   new.aux_type = type;                                   // return type
  1262.  
  1263.   new.num_parms = 0;
  1264.   if (!PR_Check(")")) {
  1265.     if (PR_Check("..."))
  1266.       new.num_parms = -1;                               // variable args
  1267.     else
  1268.       do {
  1269.     type = PR_ParseType();
  1270.     name = PR_ParseName();
  1271.     strcpy(pr_parm_names[new.num_parms], name);
  1272.     new.parm_types[new.num_parms] = type;
  1273.     new.num_parms++;
  1274.       } while (PR_Check(","));
  1275.  
  1276.     PR_Expect(")");
  1277.   }
  1278.  
  1279.   return PR_FindType(&new);
  1280. }
  1281. /*
  1282.  * ============
  1283.  * PR_Statement
  1284.  * 
  1285.  * Emits a primitive statement, returning the var it places it's value in
  1286.  * ============
  1287.  */
  1288. def_t *PR_Statement(register opcode_t * op, register def_t * var_a, register def_t * var_b)
  1289. {
  1290.   dstatement_t *statement;
  1291.   def_t *var_c;
  1292.  
  1293.   statement = &statements[numstatements];
  1294.   numstatements++;
  1295.  
  1296.   statement_linenums[statement - statements] = pr_source_line;
  1297.   statement->op = op - pr_opcodes;
  1298.   statement->a = var_a ? var_a->ofs : 0;
  1299.   statement->b = var_b ? var_b->ofs : 0;
  1300.   if (op->type_c == &def_void || op->right_associative) {
  1301.     var_c = NULL;
  1302.     statement->c = 0;                                   // ifs, gotos, and assignments
  1303.     // don't need vars allocated
  1304.  
  1305.   }
  1306.   else {                                       // allocate result space
  1307.  
  1308.     var_c = (def_t *)kmalloc(sizeof(def_t));
  1309.     //memset(var_c, 0, sizeof(def_t));
  1310.     var_c->ofs = numpr_globals;
  1311.     var_c->type = op->type_c->type;
  1312.  
  1313.     statement->c = numpr_globals;
  1314.     numpr_globals += type_size[op->type_c->type->type];
  1315.   }
  1316.  
  1317.   if (op->right_associative)
  1318.     return var_a;
  1319.   return var_c;
  1320. }
  1321.  
  1322. /*
  1323.  * ============
  1324.  * PR_ParseImmediate
  1325.  * 
  1326.  * Looks for a preexisting constant
  1327.  * ============
  1328.  */
  1329. def_t *PR_ParseImmediate(void)
  1330. {
  1331.   def_t *cn;
  1332.  
  1333. // check for a constant with the same value
  1334.   for (cn = pr.def_head.next; cn; cn = cn->next) {
  1335.     if (!cn->initialized)
  1336.       continue;
  1337.     if (cn->type != pr_immediate_type)
  1338.       continue;
  1339.     if (pr_immediate_type == &type_string) {
  1340.       if (!strcmp(G_STRING(cn->ofs), pr_immediate_string)) {
  1341.     PR_Lex();
  1342.     return cn;
  1343.       }
  1344.     }
  1345.     else if (pr_immediate_type == &type_float) {
  1346.       if (G_FLOAT(cn->ofs) == pr_immediate._float) {
  1347.     PR_Lex();
  1348.     return cn;
  1349.       }
  1350.     }
  1351.     else if (pr_immediate_type == &type_vector) {
  1352.       if ((G_FLOAT(cn->ofs) == pr_immediate.vector[0])
  1353.       && (G_FLOAT(cn->ofs + 1) == pr_immediate.vector[1])
  1354.       && (G_FLOAT(cn->ofs + 2) == pr_immediate.vector[2])) {
  1355.     PR_Lex();
  1356.     return cn;
  1357.       }
  1358.     }
  1359.     else
  1360.       PR_ParseError("weird immediate type");
  1361.   }
  1362.  
  1363. // allocate a new one
  1364.   cn = (def_t *)kmalloc(sizeof(def_t));
  1365.   cn->next = NULL;
  1366.  
  1367.   pr.def_tail->next = cn;
  1368.  
  1369.   pr.def_tail = cn;
  1370.  
  1371.   cn->search_next = pr.search;
  1372.  
  1373.   pr.search = cn;
  1374.  
  1375.   cn->type = pr_immediate_type;
  1376.   cn->name = "IMMEDIATE";
  1377.   cn->initialized = 1;
  1378.   cn->scope = NULL;                                   // always share immediates
  1379.  
  1380. // copy the immediate to the global area
  1381.   cn->ofs = numpr_globals;
  1382.   pr_global_defs[cn->ofs] = cn;
  1383.   numpr_globals += type_size[pr_immediate_type->type];
  1384.   if (pr_immediate_type == &type_string)
  1385.     pr_immediate.string = CopyString(pr_immediate_string);
  1386.  
  1387.   memcpy(pr_globals + cn->ofs, &pr_immediate, 4 * type_size[pr_immediate_type->type]);
  1388.  
  1389.   PR_Lex();
  1390.  
  1391.   return cn;
  1392. }
  1393.  
  1394. /*
  1395.  * ============
  1396.  * PR_ParseFunctionCall
  1397.  * ============
  1398.  */
  1399. def_t *PR_ParseFunctionCall(register def_t * func)
  1400. {
  1401.   def_t *e;
  1402.   int arg;
  1403.   type_t *t;
  1404.  
  1405.   t = func->type;
  1406.  
  1407.   if (t->type != ev_function)
  1408.     PR_ParseError("not a function");
  1409.  
  1410. // copy the arguments to the global parameter variables
  1411.   arg = 0;
  1412.   if (!PR_Check(")")) {
  1413.     do {
  1414.       if (t->num_parms != -1 && arg >= t->num_parms)
  1415.     PR_ParseError("too many parameters");
  1416.       e = PR_Expression(TOP_PRIORITY);
  1417.  
  1418.       if (arg == 0 && func->name) {
  1419.     // save information for model and sound caching
  1420.     if (!strncmp(func->name, "precache_sound", 14))
  1421.       PrecacheSound(e, func->name[14]);
  1422.     else if (!strncmp(func->name, "precache_model", 14))
  1423.       PrecacheModel(e, func->name[14]);
  1424.     else if (!strncmp(func->name, "precache_file", 13))
  1425.       PrecacheFile(e, func->name[13]);
  1426.       }
  1427.  
  1428.       if (t->num_parms != -1 && (e->type != t->parm_types[arg]))
  1429.     PR_ParseError("type mismatch on parm %i", arg);
  1430.       // a vector copy will copy everything
  1431.       def_parms[arg].type = t->parm_types[arg];
  1432.       PR_Statement(&pr_opcodes[OP_STORE_V], e, &def_parms[arg]);
  1433.       arg++;
  1434.     } while (PR_Check(","));
  1435.  
  1436.     if (t->num_parms != -1 && arg != t->num_parms)
  1437.       PR_ParseError("too few parameters");
  1438.     PR_Expect(")");
  1439.   }
  1440.   if (arg > 8)
  1441.     PR_ParseError("More than eight parameters");
  1442.  
  1443.   PR_Statement(&pr_opcodes[OP_CALL0 + arg], func, 0);
  1444.  
  1445.   def_ret.type = t->aux_type;
  1446.   return &def_ret;
  1447. }
  1448.  
  1449. /*
  1450.  * ============
  1451.  * PR_GetDef
  1452.  * 
  1453.  * If type is NULL, it will match any type
  1454.  * If allocate is TRUE, a new def will be allocated if it can't be found
  1455.  * ============
  1456.  */
  1457. def_t *PR_GetDef(register type_t * type, register char *name, register def_t * scope, register bool allocate)
  1458. {
  1459.   def_t *def, **old;
  1460.   char element[MAX_NAME];
  1461.  
  1462. // see if the name is already in use
  1463.   old = &pr.search;
  1464.   for (def = *old; def; old = &def->search_next, def = *old)
  1465.     if (!strcmp(def->name, name)) {
  1466.       if (def->scope && def->scope != scope)
  1467.     continue;                                   // in a different function
  1468.  
  1469.       if (type && def->type != type)
  1470.     PR_ParseError("Type mismatch on redeclaration of %s", name);
  1471.  
  1472.       // move to head of list to find fast next time
  1473.       *old = def->search_next;
  1474.  
  1475.       def->search_next = pr.search;
  1476.  
  1477.       pr.search = def;
  1478.  
  1479.       return def;
  1480.     }
  1481.  
  1482.   if (!allocate)
  1483.     return NULL;
  1484.  
  1485. // allocate a new def
  1486.   def = (def_t *)kmalloc(sizeof(def_t));
  1487.   //memset(def, 0, sizeof(*def));
  1488.   def->next = NULL;
  1489.   pr.def_tail->next = def;
  1490.  
  1491.   pr.def_tail = def;
  1492.  
  1493.   def->search_next = pr.search;
  1494.  
  1495.   pr.search = def;
  1496.  
  1497.   //def->name = (char *)kmalloc(strlen(name) + 1);
  1498.   //strcpy(def->name, name);
  1499.   def->name = smalloc(name);
  1500.   def->type = type;
  1501.  
  1502.   def->scope = scope;
  1503.  
  1504.   def->ofs = numpr_globals;
  1505.   pr_global_defs[numpr_globals] = def;
  1506.  
  1507. //
  1508.   // make automatic defs for the vectors elements
  1509.   // .origin can be accessed as .origin_x, .origin_y, and .origin_z
  1510.   //
  1511.   if (type->type == ev_vector) {
  1512.     sprintf(element, "%s_x", name);
  1513.     PR_GetDef(&type_float, element, scope, TRUE);
  1514.  
  1515.     sprintf(element, "%s_y", name);
  1516.     PR_GetDef(&type_float, element, scope, TRUE);
  1517.  
  1518.     sprintf(element, "%s_z", name);
  1519.     PR_GetDef(&type_float, element, scope, TRUE);
  1520.   }
  1521.   else
  1522.     numpr_globals += type_size[type->type];
  1523.  
  1524.   if (type->type == ev_field) {
  1525.     *(int *)&pr_globals[def->ofs] = pr.size_fields;
  1526.  
  1527.     if (type->aux_type->type == ev_vector) {
  1528.       sprintf(element, "%s_x", name);
  1529.       PR_GetDef(&type_floatfield, element, scope, TRUE);
  1530.  
  1531.       sprintf(element, "%s_y", name);
  1532.       PR_GetDef(&type_floatfield, element, scope, TRUE);
  1533.  
  1534.       sprintf(element, "%s_z", name);
  1535.       PR_GetDef(&type_floatfield, element, scope, TRUE);
  1536.     }
  1537.     else
  1538.       pr.size_fields += type_size[type->aux_type->type];
  1539.   }
  1540.  
  1541. //      if (pr_dumpasm)
  1542.   //              PR_PrintOfs (def->ofs);
  1543.  
  1544.   return def;
  1545. }
  1546.  
  1547. /*
  1548.  * ============
  1549.  * PR_ParseValue
  1550.  * 
  1551.  * Returns the global ofs for the current token
  1552.  * ============
  1553.  */
  1554. def_t *PR_ParseValue(void)
  1555. {
  1556.   def_t *d;
  1557.   char *name;
  1558.  
  1559. // if the token is an immediate, allocate a constant for it
  1560.   if (pr_token_type == tt_immediate)
  1561.     return PR_ParseImmediate();
  1562.  
  1563.   name = PR_ParseName();
  1564.  
  1565. // look through the defs
  1566.   d = PR_GetDef(NULL, name, pr_scope, FALSE);
  1567.   if (!d)
  1568.     PR_ParseError("Unknown value \"%s\"", name);
  1569.   return d;
  1570. }
  1571.  
  1572. /*
  1573.  * ============
  1574.  * PR_Term
  1575.  * ============
  1576.  */
  1577. def_t *PR_Term(void)
  1578. {
  1579.   def_t *e, *e2;
  1580.   etype_t t;
  1581.  
  1582.   if (PR_Check("!")) {
  1583.     e = PR_Expression(NOT_PRIORITY);
  1584.     t = e->type->type;
  1585.     if (t == ev_float)
  1586.       e2 = PR_Statement(&pr_opcodes[OP_NOT_F], e, 0);
  1587.     else if (t == ev_string)
  1588.       e2 = PR_Statement(&pr_opcodes[OP_NOT_S], e, 0);
  1589.     else if (t == ev_entity)
  1590.       e2 = PR_Statement(&pr_opcodes[OP_NOT_ENT], e, 0);
  1591.     else if (t == ev_vector)
  1592.       e2 = PR_Statement(&pr_opcodes[OP_NOT_V], e, 0);
  1593.     else if (t == ev_function)
  1594.       e2 = PR_Statement(&pr_opcodes[OP_NOT_FNC], e, 0);
  1595.     else {
  1596.       e2 = NULL;                                   // shut up compiler warning;
  1597.  
  1598.       PR_ParseError("type mismatch for !");
  1599.     }
  1600.     return e2;
  1601.   }
  1602.  
  1603.   if (PR_Check("(")) {
  1604.     e = PR_Expression(TOP_PRIORITY);
  1605.     PR_Expect(")");
  1606.     return e;
  1607.   }
  1608.  
  1609.   return PR_ParseValue();
  1610. }
  1611.  
  1612. /*
  1613.  * ==============
  1614.  * PR_Expression
  1615.  * ==============
  1616.  */
  1617.  
  1618. def_t *PR_Expression(register int priority)
  1619. {
  1620.   opcode_t *op, *oldop;
  1621.   def_t *e, *e2;
  1622.   etype_t type_a, type_b, type_c;
  1623.  
  1624.   if (priority == 0)
  1625.     return PR_Term();
  1626.  
  1627.   e = PR_Expression(priority - 1);
  1628.  
  1629.   while (1) {
  1630.     if (priority == 1 && PR_Check("("))
  1631.       return PR_ParseFunctionCall(e);
  1632.  
  1633.     for (op = pr_opcodes; op->name; op++) {
  1634.       if (op->priority != priority)
  1635.     continue;
  1636.       if (!PR_Check(op->name))
  1637.     continue;
  1638.       if (op->right_associative) {
  1639.     // if last statement is an indirect, change it to an address of
  1640.     if ((unsigned)(statements[numstatements - 1].op - OP_LOAD_F) < 6) {
  1641.       statements[numstatements - 1].op = OP_ADDRESS;
  1642.       def_pointer.type->aux_type = e->type;
  1643.       e->type = def_pointer.type;
  1644.     }
  1645.     e2 = PR_Expression(priority);
  1646.       }
  1647.       else
  1648.     e2 = PR_Expression(priority - 1);
  1649.  
  1650.       // type check
  1651.       type_a = e->type->type;
  1652.       type_b = e2->type->type;
  1653.  
  1654.       if (op->name[0] == '.')                               // field access gets type from field
  1655.        {
  1656.     if (e2->type->aux_type)
  1657.       type_c = e2->type->aux_type->type;
  1658.     else
  1659.       type_c = -1;                                   // not a field
  1660.  
  1661.       }
  1662.       else
  1663.     type_c = ev_void;
  1664.  
  1665.       oldop = op;
  1666.       while (type_a != op->type_a->type->type
  1667.          || type_b != op->type_b->type->type
  1668.          || (type_c != ev_void && type_c != op->type_c->type->type)) {
  1669.     op++;
  1670.     if (!op->name || strcmp(op->name, oldop->name))
  1671.       PR_ParseError("type mismatch for %s", oldop->name);
  1672.       }
  1673.  
  1674.       if (type_a == ev_pointer && type_b != e->type->aux_type->type)
  1675.     PR_ParseError("type mismatch for %s", op->name);
  1676.  
  1677.       if (op->right_associative)
  1678.     e = PR_Statement(op, e2, e);
  1679.       else
  1680.     e = PR_Statement(op, e, e2);
  1681.  
  1682.       if (type_c != ev_void)                               // field access gets type from field
  1683.  
  1684.     e->type = e2->type->aux_type;
  1685.  
  1686.       break;
  1687.     }
  1688.     if (!op->name)
  1689.       break;                                       // next token isn't at this priority level
  1690.  
  1691.   }
  1692.  
  1693.   return e;
  1694. }
  1695.  
  1696. /*
  1697.  * ============
  1698.  * PR_ParseStatement
  1699.  * 
  1700.  * ============
  1701.  */
  1702. void PR_ParseDefs(void);
  1703. void PR_ParseStatement(void)
  1704. {
  1705.   def_t *e;
  1706.   dstatement_t *patch1, *patch2;
  1707.  
  1708.   if (PR_Check("{")) {
  1709.     do {
  1710.       PR_ParseStatement();
  1711.     } while (!PR_Check("}"));
  1712.     return;
  1713.   }
  1714.  
  1715.   if (PR_Check("return")) {
  1716.     if (PR_Check(";")) {
  1717.       PR_Statement(&pr_opcodes[OP_RETURN], 0, 0);
  1718.       return;
  1719.     }
  1720.     e = PR_Expression(TOP_PRIORITY);
  1721.     PR_Expect(";");
  1722.     PR_Statement(&pr_opcodes[OP_RETURN], e, 0);
  1723.     return;
  1724.   }
  1725.  
  1726.   if (PR_Check("while")) {
  1727.     PR_Expect("(");
  1728.     patch2 = &statements[numstatements];
  1729.     e = PR_Expression(TOP_PRIORITY);
  1730.     PR_Expect(")");
  1731.     patch1 = &statements[numstatements];
  1732.     PR_Statement(&pr_opcodes[OP_IFNOT], e, 0);
  1733.     PR_ParseStatement();
  1734.     junkdef.ofs = patch2 - &statements[numstatements];
  1735.     PR_Statement(&pr_opcodes[OP_GOTO], &junkdef, 0);
  1736.     patch1->b = &statements[numstatements] - patch1;
  1737.     return;
  1738.   }
  1739.  
  1740.   if (PR_Check("do")) {
  1741.     patch1 = &statements[numstatements];
  1742.     PR_ParseStatement();
  1743.     PR_Expect("while");
  1744.     PR_Expect("(");
  1745.     e = PR_Expression(TOP_PRIORITY);
  1746.     PR_Expect(")");
  1747.     PR_Expect(";");
  1748.     junkdef.ofs = patch1 - &statements[numstatements];
  1749.     PR_Statement(&pr_opcodes[OP_IF], e, &junkdef);
  1750.     return;
  1751.   }
  1752.  
  1753.   if (PR_Check("local")) {
  1754.     PR_ParseDefs();
  1755.     locals_end = numpr_globals;
  1756.     return;
  1757.   }
  1758.  
  1759.   if (PR_Check("if")) {
  1760.     PR_Expect("(");
  1761.     e = PR_Expression(TOP_PRIORITY);
  1762.     PR_Expect(")");
  1763.  
  1764.     patch1 = &statements[numstatements];
  1765.     PR_Statement(&pr_opcodes[OP_IFNOT], e, 0);
  1766.  
  1767.     PR_ParseStatement();
  1768.  
  1769.     if (PR_Check("else")) {
  1770.       patch2 = &statements[numstatements];
  1771.       PR_Statement(&pr_opcodes[OP_GOTO], 0, 0);
  1772.       patch1->b = &statements[numstatements] - patch1;
  1773.       PR_ParseStatement();
  1774.       patch2->a = &statements[numstatements] - patch2;
  1775.     }
  1776.     else
  1777.       patch1->b = &statements[numstatements] - patch1;
  1778.  
  1779.     return;
  1780.   }
  1781.  
  1782.   PR_Expression(TOP_PRIORITY);
  1783.   PR_Expect(";");
  1784. }
  1785.  
  1786. /*
  1787.  * ==============
  1788.  * PR_ParseState
  1789.  * 
  1790.  * States are special functions made for convenience.  They automatically
  1791.  * set frame, nextthink (implicitly), and think (allowing forward definitions).
  1792.  * 
  1793.  * // void() name = [framenum, nextthink] {code}
  1794.  * // expands to:
  1795.  * // function void name ()
  1796.  * // {
  1797.  * //           self.frame=framenum;
  1798.  * //           self.nextthink = time + 0.1;
  1799.  * //           self.think = nextthink
  1800.  * //           <code>
  1801.  * // };
  1802.  * ==============
  1803.  */
  1804. void PR_ParseState(void)
  1805. {
  1806.   char *name;
  1807.   def_t *s1, *def;
  1808.  
  1809.   if (pr_token_type != tt_immediate || pr_immediate_type != &type_float)
  1810.     PR_ParseError("state frame must be a number");
  1811.   s1 = PR_ParseImmediate();
  1812.  
  1813.   PR_Expect(",");
  1814.  
  1815.   name = PR_ParseName();
  1816.   def = PR_GetDef(&type_function, name, 0, TRUE);
  1817.  
  1818.   PR_Expect("]");
  1819.  
  1820.   PR_Statement(&pr_opcodes[OP_STATE], s1, def);
  1821. }
  1822.  
  1823. /*
  1824.  * ============
  1825.  * PR_ParseImmediateStatements
  1826.  * 
  1827.  * Parse a function body
  1828.  * ============
  1829.  */
  1830. function_t *PR_ParseImmediateStatements(register type_t * type)
  1831. {
  1832.   int i;
  1833.   function_t *f;
  1834.   def_t *defs[MAX_PARMS];
  1835.  
  1836.   f = (function_t *)kmalloc(sizeof(function_t));
  1837.  
  1838. //
  1839.   // check for builtin function definition #1, #2, etc
  1840.   //
  1841.   if (PR_Check("#")) {
  1842.     if (pr_token_type != tt_immediate
  1843.     || pr_immediate_type != &type_float
  1844.     || pr_immediate._float != (int)pr_immediate._float)
  1845.       PR_ParseError("Bad builtin immediate");
  1846.     f->builtin = (int)pr_immediate._float;
  1847.     PR_Lex();
  1848.     return f;
  1849.   }
  1850.  
  1851.   f->builtin = 0;
  1852. //
  1853.   // define the parms
  1854.   //
  1855.   for (i = 0; i < type->num_parms; i++) {
  1856.     defs[i] = PR_GetDef(type->parm_types[i], pr_parm_names[i], pr_scope, TRUE);
  1857.     f->parm_ofs[i] = defs[i]->ofs;
  1858.     if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i - 1])
  1859.       PR_ParseError("bad parm order");
  1860.   }
  1861.  
  1862.   f->code = numstatements;
  1863.  
  1864. //
  1865.   // check for a state opcode
  1866.   //
  1867.   if (PR_Check("["))
  1868.     PR_ParseState();
  1869.  
  1870. //
  1871.   // parse regular statements
  1872.   //
  1873.   PR_Expect("{");
  1874.  
  1875.   while (!PR_Check("}"))
  1876.     PR_ParseStatement();
  1877.  
  1878. // emit an end of statements opcode
  1879.   PR_Statement(pr_opcodes, 0, 0);
  1880.  
  1881.   return f;
  1882. }
  1883.  
  1884. /*
  1885.  * ================
  1886.  * PR_ParseDefs
  1887.  * 
  1888.  * Called at the outer layer and when a local statement is hit
  1889.  * ================
  1890.  */
  1891. void PR_ParseDefs(void)
  1892. {
  1893.   char *name;
  1894.   type_t *type;
  1895.   def_t *def;
  1896.   function_t *f;
  1897.   dfunction_t *df;
  1898.   int i;
  1899.   int locals_start;
  1900.  
  1901.   type = PR_ParseType();
  1902.  
  1903.   if (pr_scope && (type->type == ev_field || type->type == ev_function))
  1904.     PR_ParseError("Fields and functions must be global");
  1905.  
  1906.   do {
  1907.     name = PR_ParseName();
  1908.  
  1909.     def = PR_GetDef(type, name, pr_scope, TRUE);
  1910.  
  1911. // check for an initialization
  1912.     if (PR_Check("=")) {
  1913.       if (def->initialized)
  1914.     PR_ParseError("%s redeclared", name);
  1915.  
  1916.       if (type->type == ev_function) {
  1917.     locals_start = locals_end = numpr_globals;
  1918.     pr_scope = def;
  1919.     f = PR_ParseImmediateStatements(type);
  1920.     pr_scope = NULL;
  1921.     def->initialized = 1;
  1922.     G_FUNCTION(def->ofs) = numfunctions;
  1923.     f->def = def;
  1924. //                              if (pr_dumpasm)
  1925.     //                                      PR_PrintFunction (def);
  1926.  
  1927.     // fill in the dfunction
  1928.     df = &functions[numfunctions];
  1929.     numfunctions++;
  1930.     if (f->builtin)
  1931.       df->first_statement = -f->builtin;
  1932.     else
  1933.       df->first_statement = f->code;
  1934.     df->s_name = CopyString(f->def->name);
  1935.     df->s_file = s_file;
  1936.     df->numparms = f->def->type->num_parms;
  1937.     df->locals = locals_end - locals_start;
  1938.     df->parm_start = locals_start;
  1939.     for (i = 0; i < df->numparms; i++)
  1940.       df->parm_size[i] = type_size[f->def->type->parm_types[i]->type];
  1941.  
  1942.     continue;
  1943.       }
  1944.       else if (pr_immediate_type != type)
  1945.     PR_ParseError("wrong immediate type for %s", name);
  1946.  
  1947.       def->initialized = 1;
  1948.       memcpy(pr_globals + def->ofs, &pr_immediate, 4 * type_size[pr_immediate_type->type]);
  1949.       PR_Lex();
  1950.     }
  1951.  
  1952.   } while (PR_Check(","));
  1953.  
  1954.   PR_Expect(";");
  1955. }
  1956.  
  1957. /*
  1958.  * ============
  1959.  * PR_CompileFile
  1960.  * 
  1961.  * compiles the 0 terminated text, adding defintions to the pr structure
  1962.  * ============
  1963.  */
  1964. bool PR_CompileFile(register char *string, register char *filename)
  1965. {
  1966.   if (!pr.memory) {
  1967.     eprintf("PR_CompileFile: Didn't clear");
  1968.     return FALSE;
  1969.   }
  1970.  
  1971.   PR_ClearGrabMacros();                                   // clear the frame macros
  1972.  
  1973.   pr_file_p = string;
  1974.   s_file = CopyString(filename);
  1975.  
  1976.   pr_source_line = 0;
  1977.  
  1978.   PR_NewLine();
  1979.  
  1980.   PR_Lex();                                       // read first token
  1981.  
  1982.   while (pr_token_type != tt_eof) {
  1983.     if (setjmp(pr_parse_abort)) {
  1984.       if (++pr_error_count > MAX_ERRORS)
  1985.     return FALSE;
  1986.       PR_SkipToSemicolon();
  1987.       if (pr_token_type == tt_eof)
  1988.     return FALSE;
  1989.     }
  1990.  
  1991.     pr_scope = NULL;                                   // outside all functions
  1992.  
  1993.     PR_ParseDefs();
  1994.   }
  1995.  
  1996.   return (pr_error_count == 0);
  1997. }
  1998. /*
  1999.  * ===============
  2000.  * PR_String
  2001.  * 
  2002.  * Returns a string suitable for printing (no newlines, max 60 chars length)
  2003.  * ===============
  2004.  */
  2005. char *PR_String(register char *string)
  2006. {
  2007.   static char buf[80];
  2008.   char *s;
  2009.  
  2010.   s = buf;
  2011.   *s++ = '"';
  2012.   while (string && *string) {
  2013.     if (s == buf + sizeof(buf) - 2)
  2014.       break;
  2015.     if (*string == '\n') {
  2016.       *s++ = '\\';
  2017.       *s++ = 'n';
  2018.     }
  2019.     else if (*string == '"') {
  2020.       *s++ = '\\';
  2021.       *s++ = '"';
  2022.     }
  2023.     else
  2024.       *s++ = *string;
  2025.     string++;
  2026.     if (s - buf > 60) {
  2027.       *s++ = '.';
  2028.       *s++ = '.';
  2029.       *s++ = '.';
  2030.       break;
  2031.     }
  2032.   }
  2033.   *s++ = '"';
  2034.   *s++ = 0;
  2035.   return buf;
  2036. }
  2037.  
  2038. def_t *PR_DefForFieldOfs(register gofs_t ofs)
  2039. {
  2040.   def_t *d;
  2041.  
  2042.   for (d = pr.def_head.next; d; d = d->next) {
  2043.     if (d->type->type != ev_field)
  2044.       continue;
  2045.     if (*((int *)&pr_globals[d->ofs]) == ofs)
  2046.       return d;
  2047.   }
  2048.   eprintf("PR_DefForFieldOfs: couldn't find %i", ofs);
  2049.   return NULL;
  2050. }
  2051.  
  2052. /*
  2053.  * ============
  2054.  * PR_ValueString
  2055.  * 
  2056.  * Returns a string describing *data in a type specific manner
  2057.  * =============
  2058.  */
  2059. char *PR_ValueString(register etype_t type, register void *val)
  2060. {
  2061.   static char line[256];
  2062.   def_t *def;
  2063.   dfunction_t *f;
  2064.  
  2065.   switch (type) {
  2066.     case ev_string:
  2067.       sprintf(line, "%s", PR_String(strings + *(int *)val));
  2068.       break;
  2069.     case ev_entity:
  2070.       sprintf(line, "entity %i", *(int *)val);
  2071.       break;
  2072.     case ev_function:
  2073.       f = functions + *(int *)val;
  2074.       if (!f)
  2075.     sprintf(line, "undefined function");
  2076.       else
  2077.     sprintf(line, "%s()", strings + f->s_name);
  2078.       break;
  2079.     case ev_field:
  2080.       def = PR_DefForFieldOfs(*(int *)val);
  2081.       sprintf(line, ".%s", def->name);
  2082.       break;
  2083.     case ev_void:
  2084.       sprintf(line, "void");
  2085.       break;
  2086.     case ev_float:
  2087.       sprintf(line, "%g", *(float *)val);
  2088.       break;
  2089.     case ev_vector:
  2090.       sprintf(line, "'%g %g %g'", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]);
  2091.       break;
  2092.     case ev_pointer:
  2093.       sprintf(line, "pointer");
  2094.       break;
  2095.     default:
  2096.       sprintf(line, "bad type %i", type);
  2097.       break;
  2098.   }
  2099.  
  2100.   return line;
  2101. }
  2102.  
  2103. /*
  2104.  * ============
  2105.  * PR_GlobalString
  2106.  * 
  2107.  * Returns a string with a description and the contents of a global,
  2108.  * padded to 20 field width
  2109.  * ============
  2110.  */
  2111. char *PR_GlobalStringNoContents(register gofs_t ofs)
  2112. {
  2113.   int i;
  2114.   def_t *def;
  2115.   void *val;
  2116.   static char line[128];
  2117.  
  2118.   val = (void *)&pr_globals[ofs];
  2119.   def = pr_global_defs[ofs];
  2120.   if (!def)
  2121. //              Error ("PR_GlobalString: no def for %i", ofs);
  2122.     sprintf(line, "%i(???)", ofs);
  2123.   else
  2124.     sprintf(line, "%i(%s)", ofs, def->name);
  2125.  
  2126.   i = strlen(line);
  2127.   for (; i < 16; i++)
  2128.     strcat(line, " ");
  2129.   strcat(line, " ");
  2130.  
  2131.   return line;
  2132. }
  2133.  
  2134. char *PR_GlobalString(register gofs_t ofs)
  2135. {
  2136.   char *s;
  2137.   int i;
  2138.   def_t *def;
  2139.   void *val;
  2140.   static char line[128];
  2141.  
  2142.   val = (void *)&pr_globals[ofs];
  2143.   def = pr_global_defs[ofs];
  2144.   if (!def)
  2145.     return PR_GlobalStringNoContents(ofs);
  2146.   if (def->initialized && def->type->type != ev_function) {
  2147.     s = PR_ValueString(def->type->type, &pr_globals[ofs]);
  2148.     sprintf(line, "%i(%s)", ofs, s);
  2149.   }
  2150.   else
  2151.     sprintf(line, "%i(%s)", ofs, def->name);
  2152.  
  2153.   i = strlen(line);
  2154.   for (; i < 16; i++)
  2155.     strcat(line, " ");
  2156.   strcat(line, " ");
  2157.  
  2158.   return line;
  2159. }
  2160.  
  2161. /*
  2162.  * ============
  2163.  * PR_PrintOfs
  2164.  * ============
  2165.  */
  2166. void PR_PrintOfs(register gofs_t ofs)
  2167. {
  2168.   mprintf("%s\n", PR_GlobalString(ofs));
  2169. }
  2170.  
  2171. /*
  2172.  * =================
  2173.  * PR_PrintStatement
  2174.  * =================
  2175.  */
  2176. void PR_PrintStatement(register dstatement_t * s)
  2177. {
  2178.   int i;
  2179.  
  2180.   mprintf("%4i : %4i : %s ", (int)(s - statements), statement_linenums[s - statements], pr_opcodes[s->op].opname);
  2181.   i = strlen(pr_opcodes[s->op].opname);
  2182.   for (; i < 10; i++)
  2183.     mprintf(" ");
  2184.  
  2185.   if (s->op == OP_IF || s->op == OP_IFNOT)
  2186.     mprintf("%sbranch %i", PR_GlobalString(s->a), s->b);
  2187.   else if (s->op == OP_GOTO) {
  2188.     mprintf("branch %i", s->a);
  2189.   }
  2190.   else if ((unsigned)(s->op - OP_STORE_F) < 6) {
  2191.     mprintf("%s", PR_GlobalString(s->a));
  2192.     mprintf("%s", PR_GlobalStringNoContents(s->b));
  2193.   }
  2194.   else {
  2195.     if (s->a)
  2196.       mprintf("%s", PR_GlobalString(s->a));
  2197.     if (s->b)
  2198.       mprintf("%s", PR_GlobalString(s->b));
  2199.     if (s->c)
  2200.       mprintf("%s", PR_GlobalStringNoContents(s->c));
  2201.   }
  2202.   mprintf("\n");
  2203. }
  2204.  
  2205. /*
  2206.  * ============
  2207.  * PR_PrintDefs
  2208.  * ============
  2209.  */
  2210. void PR_PrintDefs(void)
  2211. {
  2212.   def_t *d;
  2213.  
  2214.   for (d = pr.def_head.next; d; d = d->next)
  2215.     PR_PrintOfs(d->ofs);
  2216. }
  2217.  
  2218. /*
  2219.  * ==============
  2220.  * PR_BeginCompilation
  2221.  * 
  2222.  * called before compiling a batch of files, clears the pr struct
  2223.  * ==============
  2224.  */
  2225. void PR_BeginCompilation(register void *memory, register int memsize)
  2226. {
  2227.   int i;
  2228.  
  2229.   pr.memory = memory;
  2230.   pr.max_memory = memsize;
  2231.  
  2232.   numpr_globals = RESERVED_OFS;
  2233.   pr.def_tail = &pr.def_head;
  2234.  
  2235.   for (i = 0; i < RESERVED_OFS; i++)
  2236.     pr_global_defs[i] = &def_void;
  2237.  
  2238. // link the function type in so state forward declarations match proper type
  2239.   pr.types = &type_function;
  2240.   type_function.next = NULL;
  2241.   pr_error_count = 0;
  2242. }
  2243.  
  2244. /*
  2245.  * ==============
  2246.  * PR_FinishCompilation
  2247.  * 
  2248.  * called after all files are compiled to check for errors
  2249.  * Returns FALSE if errors were detected.
  2250.  * ==============
  2251.  */
  2252. bool PR_FinishCompilation(void)
  2253. {
  2254.   def_t *d;
  2255.   bool errors;
  2256.  
  2257.   errors = FALSE;
  2258.  
  2259. // check to make sure all functions prototyped have code
  2260.   for (d = pr.def_head.next; d; d = d->next) {
  2261.     if (d->type->type == ev_function && !d->scope)                   // function parms are ok
  2262.      {
  2263. //                      f = G_FUNCTION(d->ofs);
  2264.       //                      if (!f || (!f->code && !f->builtin) )
  2265.       if (!d->initialized) {
  2266.     eprintf("function %s was not defined\n", d->name);
  2267.     errors = TRUE;
  2268.       }
  2269.     }
  2270.   }
  2271.  
  2272.   return !errors;
  2273. }
  2274.  
  2275. //=============================================================================
  2276.  
  2277. /*
  2278.  * ============
  2279.  * PR_WriteProgdefs
  2280.  * 
  2281.  * Writes the global and entity structures out
  2282.  * Returns a crc of the header, to be stored in the progs file for comparison
  2283.  * at load time.
  2284.  * ============
  2285.  */
  2286. int PR_WriteProgdefs(register char *filename)
  2287. {
  2288.   def_t *d;
  2289.   FILE *f;
  2290.   unsigned short int crc;
  2291.   int c;
  2292.  
  2293.   mprintf("writing %s\n", filename);
  2294.   f = fopen(filename, "w");
  2295.  
  2296. // print global vars until the first field is defined
  2297.   fprintf(f, "\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{\tint\tpad[%i];\n", RESERVED_OFS);
  2298.   for (d = pr.def_head.next; d; d = d->next) {
  2299.     if (!strcmp(d->name, "end_sys_globals"))
  2300.       break;
  2301.  
  2302.     switch (d->type->type) {
  2303.       case ev_float:
  2304.     fprintf(f, "\tfloat\t%s;\n", d->name);
  2305.     break;
  2306.       case ev_vector:
  2307.     fprintf(f, "\tvec3_t\t%s;\n", d->name);
  2308.     d = d->next->next->next;                           // skip the elements
  2309.  
  2310.     break;
  2311.       case ev_string:
  2312.     fprintf(f, "\tstring_t\t%s;\n", d->name);
  2313.     break;
  2314.       case ev_function:
  2315.     fprintf(f, "\tfunc_t\t%s;\n", d->name);
  2316.     break;
  2317.       case ev_entity:
  2318.     fprintf(f, "\tint\t%s;\n", d->name);
  2319.     break;
  2320.       default:
  2321.     fprintf(f, "\tint\t%s;\n", d->name);
  2322.     break;
  2323.     }
  2324.   }
  2325.   fprintf(f, "} globalvars_t;\n\n");
  2326.  
  2327. // print all fields
  2328.   fprintf(f, "typedef struct\n{\n");
  2329.   for (d = pr.def_head.next; d; d = d->next) {
  2330.     if (!strcmp(d->name, "end_sys_fields"))
  2331.       break;
  2332.  
  2333.     if (d->type->type != ev_field)
  2334.       continue;
  2335.  
  2336.     switch (d->type->aux_type->type) {
  2337.       case ev_float:
  2338.     fprintf(f, "\tfloat\t%s;\n", d->name);
  2339.     break;
  2340.       case ev_vector:
  2341.     fprintf(f, "\tvec3_t\t%s;\n", d->name);
  2342.     d = d->next->next->next;                           // skip the elements
  2343.  
  2344.     break;
  2345.       case ev_string:
  2346.     fprintf(f, "\tstring_t\t%s;\n", d->name);
  2347.     break;
  2348.       case ev_function:
  2349.     fprintf(f, "\tfunc_t\t%s;\n", d->name);
  2350.     break;
  2351.       case ev_entity:
  2352.     fprintf(f, "\tint\t%s;\n", d->name);
  2353.     break;
  2354.       default:
  2355.     fprintf(f, "\tint\t%s;\n", d->name);
  2356.     break;
  2357.     }
  2358.   }
  2359.   fprintf(f, "} entvars_t;\n\n");
  2360.  
  2361.   fclose(f);
  2362.  
  2363. // do a crc of the file
  2364.   CRC_Init(&crc);
  2365.   f = fopen(filename, "r+");
  2366.   while ((c = fgetc(f)) != EOF)
  2367.     CRC_ProcessByte(&crc, (unsigned char)c);
  2368.  
  2369.   fprintf(f, "#define PROGHEADER_CRC %i\n", crc);
  2370.   fclose(f);
  2371.  
  2372.   return crc;
  2373. }
  2374.  
  2375. void PrintFunction(register char *name)
  2376. {
  2377.   int i;
  2378.   dstatement_t *ds;
  2379.   dfunction_t *df;
  2380.  
  2381.   for (i = 0; i < numfunctions; i++)
  2382.     if (!strcmp(name, strings + functions[i].s_name))
  2383.       break;
  2384.   if (i == numfunctions)
  2385.     eprintf("No function names \"%s\"", name);
  2386.   else {
  2387.     df = functions + i;
  2388.  
  2389.     mprintf("Statements for %s:\n", name);
  2390.     ds = statements + df->first_statement;
  2391.     while (1) {
  2392.       PR_PrintStatement(ds);
  2393.       if (!ds->op)
  2394.         break;
  2395.       ds++;
  2396.     }
  2397.   }
  2398. }
  2399.  
  2400. //============================================================================
  2401.  
  2402. char com_token[1024];
  2403. bool com_eof;
  2404.  
  2405. /*
  2406.  * ==============
  2407.  * COM_Parse
  2408.  * 
  2409.  * Parse a token out of a string
  2410.  * ==============
  2411.  */
  2412. char *COM_Parse(register char *data)
  2413. {
  2414.   int c;
  2415.   int len;
  2416.  
  2417.   len = 0;
  2418.   com_token[0] = 0;
  2419.  
  2420.   if (!data)
  2421.     return NULL;
  2422.  
  2423. // skip whitespace
  2424. skipwhite:
  2425.   while ((c = *data) <= ' ') {
  2426.     if (c == 0) {
  2427.       com_eof = TRUE;
  2428.       return NULL;                                   // end of file;
  2429.  
  2430.     }
  2431.     data++;
  2432.   }
  2433.  
  2434. // skip // comments
  2435.   if (c == '/' && data[1] == '/') {
  2436.     while (*data && *data != '\n')
  2437.       data++;
  2438.     goto skipwhite;
  2439.   }
  2440.  
  2441. // handle quoted strings specially
  2442.   if (c == '\"') {
  2443.     data++;
  2444.     do {
  2445.       c = *data++;
  2446.       if (c == '\"') {
  2447.     com_token[len] = 0;
  2448.     return data;
  2449.       }
  2450.       com_token[len] = c;
  2451.       len++;
  2452.     } while (1);
  2453.   }
  2454.  
  2455. // parse single characters
  2456.   if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':') {
  2457.     com_token[len] = c;
  2458.     len++;
  2459.     com_token[len] = 0;
  2460.     return data + 1;
  2461.   }
  2462.  
  2463. // parse a regular word
  2464.   do {
  2465.     com_token[len] = c;
  2466.     data++;
  2467.     len++;
  2468.     c = *data;
  2469.     if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':')
  2470.       break;
  2471.   } while (c > 32);
  2472.  
  2473.   com_token[len] = 0;
  2474.   return data;
  2475. }
  2476.  
  2477. //===========================================================================
  2478. //unqcc
  2479. //===========================================================================
  2480.  
  2481. FILE *DEC_ofile;
  2482. FILE *DEC_progssrc;
  2483. #ifdef    QC_PROFILE
  2484. FILE *DEC_profile;
  2485. #endif
  2486. char *DEC_FilesSeen[1024];
  2487. int DEC_FileCtr = 0;
  2488. char *DEC_Profiles[MAX_FUNCTIONS];
  2489.  
  2490. char *type_names[8] =
  2491. {"void", "string", "float", "vector", "entity", "ev_field", "void()", "ev_pointer"};
  2492.  
  2493. char *builtins[79] =
  2494. {
  2495.   NULL,
  2496.   "void (vector ang)",
  2497.   "void (entity e, vector o)",
  2498.   "void (entity e, string m)",
  2499.   "void (entity e, vector min, vector max)",
  2500.   NULL,
  2501.   "void ()",
  2502.   "float ()",
  2503.   "void (entity e, float chan, string samp, float vol, float atten)",
  2504.   "vector (vector v)",
  2505.   "void (string e)",
  2506.   "void (string e)",
  2507.   "float (vector v)",
  2508.   "float (vector v)",
  2509.   "entity ()",
  2510.   "void (entity e)",
  2511.   "void (vector v1, vector v2, float nomonsters, entity forent)",
  2512.   "entity ()",
  2513.   "entity (entity start, .string fld, string match)",
  2514.   "string (string s)",
  2515.   "string (string s)",
  2516.   "void (entity client, string s)",
  2517.   "entity (vector org, float rad)",
  2518.   "void (string s)",
  2519.   "void (entity client, string s)",
  2520.   "void (string s)",
  2521.   "string (float f)",
  2522.   "string (vector v)",
  2523.   "void ()",
  2524.   "void ()",
  2525.   "void ()",
  2526.   "void (entity e)",
  2527.   "float (float yaw, float dist)",
  2528.   NULL,
  2529.   "float (float yaw, float dist)",
  2530.   "void (float style, string value)",
  2531.   "float (float v)",
  2532.   "float (float v)",
  2533.   "float (float v)",
  2534.   NULL,
  2535.   "float (entity e)",
  2536.   "float (vector v)",
  2537.   NULL,
  2538.   "float (float f)",
  2539.   "vector (entity e, float speed)",
  2540.   "float (string s)",
  2541.   "void (string s)",
  2542.   "entity (entity e)",
  2543.   "void (vector o, vector d, float color, float count)",
  2544.   "void ()",
  2545.   NULL,
  2546.   "vector (vector v)",
  2547.   "void (float to, float f)",
  2548.   "void (float to, float f)",
  2549.   "void (float to, float f)",
  2550.   "void (float to, float f)",
  2551.   "void (float to, float f)",
  2552.   "void (float to, float f)",
  2553.   "void (float to, string s)",
  2554.   "void (float to, entity s)",
  2555.   NULL,
  2556.   NULL,
  2557.   NULL,
  2558.   NULL,
  2559.   NULL,
  2560.   NULL,
  2561.   NULL,
  2562.   "void (float step)",
  2563.   "string (string s)",
  2564.   "void (entity e)",
  2565.   "void (string s)",
  2566.   NULL,
  2567.   "void (string var, string val)",
  2568.   "void (entity client, string s)",
  2569.   "void (vector pos, string samp, float vol, float atten)",
  2570.   "string (string s)",
  2571.   "string (string s)",
  2572.   "string (string s)",
  2573.   "void (entity e)"
  2574. };
  2575.  
  2576. int DEC_GetFunctionIdxByName(register char *name)
  2577. {
  2578.   int i;
  2579.  
  2580.   for (i = 1; i < numfunctions; i++)
  2581.     if (!strcmp(name, strings + functions[i].s_name)) {
  2582.       break;
  2583.     }
  2584.   return i;
  2585. }
  2586.  
  2587. int DEC_AlreadySeen(register char *fname)
  2588. {
  2589.   int i;
  2590.   char *new;
  2591.  
  2592.   if (DEC_FileCtr > 1000)
  2593.     eprintf("DEC_AlreadySeen - too many source files.");
  2594.   else {
  2595.     for (i = 0; i < DEC_FileCtr; i++) {
  2596.       if (!strcmp(fname, DEC_FilesSeen[i]))
  2597.         return 1;
  2598.     }
  2599.  
  2600.     //new = (char *)kmalloc(strlen(fname) + 1);
  2601.     //strcpy(new, fname);
  2602.     new = smalloc(fname);
  2603.     DEC_FilesSeen[DEC_FileCtr] = new;
  2604.     DEC_FileCtr++;
  2605.  
  2606.     mprintf("decompiling %s\n", fname);
  2607.   }
  2608.   return 0;
  2609. }
  2610.  
  2611. ddef_t *DEC_GetParameter(register gofs_t ofs)
  2612. {
  2613.   int i;
  2614.   ddef_t *def;
  2615.  
  2616.   def = NULL;
  2617.  
  2618.   for (i = 0; i < numglobaldefs; i++) {
  2619.     def = &globals[i];
  2620.  
  2621.     if (def->ofs == ofs) {
  2622.       return def;
  2623.     }
  2624.   }
  2625.  
  2626.   return NULL;
  2627. }
  2628.  
  2629. /*
  2630.  * fix: same as PR_String
  2631.  */
  2632. char *DEC_String(register char *string)
  2633. {
  2634.   static char buf[255];
  2635.   char *s;
  2636.   int c = 1;
  2637.  
  2638.   s = buf;
  2639.   *s++ = '"';
  2640.   while (string && *string) {
  2641.     if (c == sizeof(buf) - 2)
  2642.       break;
  2643.     if (*string == '\n') {
  2644.       *s++ = '\\';
  2645.       *s++ = 'n';
  2646.       c++;
  2647.     }
  2648.     else if (*string == '"') {
  2649.       *s++ = '\\';
  2650.       *s++ = '"';
  2651.       c++;
  2652.     }
  2653.     else {
  2654.       *s++ = *string;
  2655.       c++;
  2656.     }
  2657.     string++;
  2658.     if (c > sizeof(buf) - 10) {
  2659.       *s++ = '.';
  2660.       *s++ = '.';
  2661.       *s++ = '.';
  2662.       c += 3;
  2663.       break;
  2664.     }
  2665.   }
  2666.   *s++ = '"';
  2667.   *s++ = 0;
  2668.   return buf;
  2669. }
  2670.  
  2671. /*
  2672.  * fix: same as PR_ValueString
  2673.  */
  2674. char *DEC_ValueString(register etype_t type, register void *val)
  2675. {
  2676.   static char line[1024];
  2677.   line[0] = '\0';
  2678.  
  2679.   switch (type) {
  2680.     case ev_string:
  2681.       sprintf(line, "%s", DEC_String(strings + *(int *)val));
  2682.       break;
  2683.     case ev_void:
  2684.       sprintf(line, "void");
  2685.       break;
  2686.     case ev_float:
  2687.       sprintf(line, "%g", *(float *)val);
  2688.       break;
  2689.     case ev_vector:
  2690.       sprintf(line, "'%g %g %g'", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]);
  2691.       break;
  2692.     default:
  2693.       sprintf(line, "bad type %i", type);
  2694.       break;
  2695.   }
  2696.  
  2697.   return line;
  2698. }
  2699.  
  2700. char *DEC_PrintParameter(register ddef_t * def)
  2701. {
  2702.   static char line[128];
  2703.   line[0] = '0';
  2704.  
  2705.   if (!strcmp(strings + def->s_name, "IMMEDIATE")) {
  2706.     sprintf(line, "%s", DEC_ValueString(def->type, &pr_globals[def->ofs]));
  2707.   }
  2708.   else
  2709.     sprintf(line, "%s %s", type_names[def->type], strings + def->s_name);
  2710.  
  2711.   return line;
  2712. }
  2713.  
  2714. void DEC_CalcProfiles(void)
  2715. {
  2716.   int i, j, ps;
  2717.   static char fname[512];
  2718.   static char line[512];
  2719.   char *new;
  2720.   dfunction_t *df;
  2721.   dstatement_t *ds, *rds;
  2722.   ddef_t *par;
  2723.   unsigned short dom;
  2724.  
  2725.   for (i = 1; i < numfunctions; i++) {
  2726.     df = functions + i;
  2727.     fname[0] = '\0';
  2728.     line[0] = '\0';
  2729.     DEC_Profiles[i] = NULL;
  2730.  
  2731.     if (df->first_statement <= 0) {
  2732.       sprintf(fname, "%s %s", builtins[-df->first_statement], strings + functions[i].s_name);
  2733.     }
  2734.     else {
  2735.       ds = statements + df->first_statement;
  2736.       rds = NULL;
  2737.  
  2738.       // find a return statement, to determine the result type
  2739.  
  2740.       while (1) {
  2741.     dom = (ds->op) % 100;
  2742.     if (!dom)
  2743.       break;
  2744.     if (dom == OP_RETURN) {
  2745.       rds = ds;
  2746. //                  break; 
  2747.     }
  2748.     ds++;
  2749.       }
  2750.  
  2751.       // print the return type 
  2752.       if ((rds != NULL) && (rds->a != 0)) {
  2753.     par = DEC_GetParameter(rds->a);
  2754.  
  2755.     if (par) {
  2756.       sprintf(fname, "%s ", type_names[par->type]);
  2757.     }
  2758.     else {
  2759.       sprintf(fname, "float /* ERROR: Could not determine return type */ ");
  2760.     }
  2761.       }
  2762.       else {
  2763.     sprintf(fname, "\nvoid ");
  2764.       }
  2765.       strcat(fname, "(");
  2766.  
  2767.       // determine overall parameter size
  2768.  
  2769.       for (j = 0, ps = 0; j < df->numparms; j++)
  2770.     ps += df->parm_size[j];
  2771.  
  2772.       if (ps > 0) {
  2773.     for (j = df->parm_start; j < (df->parm_start) + ps; j++) {
  2774.       line[0] = '\0';
  2775.       par = DEC_GetParameter(j);
  2776.  
  2777.       if (!par)
  2778.         eprintf("DEC_CalcProfiles - No parameter names with offset %i.", j);
  2779.       else {
  2780.         if (par->type == ev_vector)
  2781.           j += 2;
  2782.  
  2783.         if (j < (df->parm_start) + ps - 1) {
  2784.           sprintf(line, "%s, ", DEC_PrintParameter(par));
  2785.         }
  2786.         else {
  2787.           sprintf(line, "%s", DEC_PrintParameter(par));
  2788.         }
  2789.         strcat(fname, line);
  2790.       }
  2791.     }
  2792.       }
  2793.       strcat(fname, ") ");
  2794.       line[0] = '\0';
  2795.       sprintf(line, strings + functions[i].s_name);
  2796.       strcat(fname, line);
  2797.     }
  2798.  
  2799.     if (i >= MAX_FUNCTIONS)
  2800.       eprintf("DEC_CalcProfiles - too many functions.");
  2801.     else {
  2802.       //new = (char *)kmalloc(strlen(fname) + 1);
  2803.       //strcpy(new, fname);
  2804.       new = smalloc(fname);
  2805.       DEC_Profiles[i] = new;
  2806.     }
  2807.   }
  2808. }
  2809.  
  2810. char *DEC_Global(register gofs_t ofs, register def_t * req_t)
  2811. {
  2812.   int i;
  2813.   ddef_t *def;
  2814.   static char line[256];
  2815.   char *res;
  2816.   char found = 0;
  2817.  
  2818.   line[0] = '\0';
  2819.  
  2820.   def = NULL;
  2821.  
  2822.   for (i = 0; i < numglobaldefs; i++) {
  2823.     def = &globals[i];
  2824.     if (def->ofs == ofs) {
  2825.       oprintf("DEC_Global - Found %i at %i.\n",ofs,(int)def);
  2826.       found = 1;
  2827.       break;
  2828.     }
  2829.   }
  2830.  
  2831.   if (found) {
  2832.     if (!strcmp(strings + def->s_name, "IMMEDIATE"))
  2833.       sprintf(line, "%s", DEC_ValueString(def->type, &pr_globals[def->ofs]));
  2834.     else {
  2835.  
  2836.       sprintf(line, "%s", strings + def->s_name);
  2837.       if (def->type == ev_vector && req_t == &def_float)
  2838.     strcat(line, "_x");
  2839.     }
  2840.     //res = (char *)kmalloc(strlen(line) + 1);
  2841.     //strcpy(res, line);
  2842.     res = smalloc(line);
  2843.  
  2844.     oprintf("DEC_Global - Found \"%s\"(%i) at %i.\n",line,ofs,(int)def);
  2845.     return res;
  2846.  
  2847.   }
  2848.   return NULL;
  2849. }
  2850.  
  2851. gofs_t DEC_ScaleIndex(register dfunction_t * df, register gofs_t ofs)
  2852. {
  2853.   gofs_t nofs = 0;
  2854.  
  2855.   if (ofs > RESERVED_OFS)
  2856.     nofs = ofs - df->parm_start + RESERVED_OFS;
  2857.   else
  2858.     nofs = ofs;
  2859.  
  2860.   return nofs;
  2861. }
  2862.  
  2863. #define MAX_NO_LOCAL_IMMEDIATES 1024
  2864.  
  2865. char *DEC_Immediate(register dfunction_t * df, register gofs_t ofs, register int fun, register char *new)
  2866. {
  2867.   int i;
  2868.   gofs_t nofs;
  2869.   static char *IMMEDIATES[MAX_NO_LOCAL_IMMEDIATES];
  2870.  
  2871.   /*
  2872.    * free 'em all 
  2873.    */
  2874.   if (fun == 0) {
  2875.     oprintf("DEC_Immediate - Initializing function environment.\n");
  2876.     for (i = 0; i < MAX_NO_LOCAL_IMMEDIATES; i++)
  2877.       if (IMMEDIATES[i])
  2878.     tfree(IMMEDIATES[i]);
  2879.     memset(&IMMEDIATES, 0, MAX_NO_LOCAL_IMMEDIATES * sizeof(char *));
  2880.     return NULL;
  2881.   }
  2882.  
  2883.   nofs = DEC_ScaleIndex(df, ofs);
  2884.   oprintf("DEC_Immediate - Index scale: %i -> %i.\n",ofs,nofs);
  2885.  
  2886.   /*
  2887.    * check consistency 
  2888.    */
  2889.   if ((nofs <= 0) || (nofs > MAX_NO_LOCAL_IMMEDIATES - 1))
  2890.     eprintf("DEC_Immediate - Index (%i) out of bounds.\n", nofs);
  2891.   else {
  2892.     /*
  2893.      * insert at nofs 
  2894.      */
  2895.     if (fun == 1) {
  2896.       if (IMMEDIATES[nofs])
  2897.         tfree(IMMEDIATES[nofs]);
  2898.       IMMEDIATES[nofs] = smalloc(new);
  2899.       oprintf("DEC_Immediate - Putting \"%s\" at index %i.\n",new,nofs);
  2900.     }
  2901.  
  2902.     /*
  2903.      * get from nofs 
  2904.      */
  2905.     if (fun == 2) {
  2906.       if (IMMEDIATES[nofs]) {
  2907.         oprintf("DEC_Immediate - Reading \"%s\" at index %i.\n",IMMEDIATES[nofs],nofs);
  2908.         return smalloc(IMMEDIATES[nofs]);
  2909.       }
  2910.       else
  2911.         eprintf("DEC_Immediate - %i not defined.", nofs);
  2912.     }
  2913.   }
  2914.  
  2915.   return NULL;
  2916. }
  2917.  
  2918. char *DEC_Get(register dfunction_t * df, register gofs_t ofs, register def_t * req_t)
  2919. {
  2920.   char *arg1 = NULL;
  2921.  
  2922.   arg1 = DEC_Global(ofs, req_t);
  2923.  
  2924.   if (arg1 == NULL)
  2925.     arg1 = DEC_Immediate(df, ofs, 2, NULL);
  2926.  
  2927.   /*
  2928.    * if (arg1)
  2929.    * mprintf("DEC_Get - found \"%s\".\n",arg1);
  2930.    */
  2931.  
  2932.   return arg1;
  2933. }
  2934.  
  2935. void DEC_Indent(register int c)
  2936. {
  2937.   int i;
  2938.  
  2939.   if (c < 0)
  2940.     c = 0;
  2941.  
  2942.   for (i = 0; i < c; i++) {
  2943.     fprintf(DEC_ofile, "   ");
  2944.   }
  2945. }
  2946.  
  2947. void DEC_DecompileStatement(register dfunction_t * df, register dstatement_t * s, register int *indent)
  2948. {
  2949.   static char line[512];
  2950.   static char fnam[512];
  2951.   char *arg1, *arg2, *arg3;
  2952.   int nargs, i, j;
  2953.   dstatement_t *t;
  2954.   unsigned short dom, doc, ifc, tom;
  2955.   def_t *typ1, *typ2, *typ3;
  2956.  
  2957.   dstatement_t *k;
  2958.   int dum;
  2959.  
  2960.   arg1 = arg2 = arg3 = NULL;
  2961.  
  2962.   line[0] = '\0';
  2963.   fnam[0] = '\0';
  2964.  
  2965.   dom = s->op;
  2966.  
  2967.   doc = dom / 10000;
  2968.   ifc = (dom % 10000) / 100;
  2969.  
  2970.   /*
  2971.    * use program flow information 
  2972.    */
  2973.   for (i = 0; i < ifc; i++) {
  2974.     (*indent)--;
  2975.     fprintf(DEC_ofile, "\n");
  2976.     DEC_Indent(*indent);
  2977.     fprintf(DEC_ofile, "}\n");
  2978.   }
  2979.   for (i = 0; i < doc; i++) {
  2980.     DEC_Indent(*indent);
  2981.     fprintf(DEC_ofile, "do {\n\n");
  2982.     (*indent)++;
  2983.   }
  2984.  
  2985.   /*
  2986.    * remove all program flow information 
  2987.    */
  2988.   s->op %= 100;
  2989.  
  2990.   typ1 = pr_opcodes[s->op].type_a;
  2991.   typ2 = pr_opcodes[s->op].type_b;
  2992.   typ3 = pr_opcodes[s->op].type_c;
  2993.  
  2994.   /*
  2995.    * mprintf("DEC_DecompileStatement - decompiling %i (%i):\n",(int)(s - statements),dom);
  2996.    * DEC_PrintStatement (s);  
  2997.    */
  2998.   // states are handled at top level
  2999.   if (s->op == OP_DONE || s->op == OP_STATE) {
  3000.   }
  3001.   else if (s->op == OP_RETURN) {
  3002.     DEC_Indent(*indent);
  3003.     fprintf(DEC_ofile, "return ");
  3004.  
  3005.     if (s->a) {
  3006.       arg1 = DEC_Get(df, s->a, typ1);
  3007.       fprintf(DEC_ofile, "( %s )", arg1);
  3008.     }
  3009.  
  3010.     fprintf(DEC_ofile, ";\n");
  3011.   }
  3012.   else if ((OP_MUL_F <= s->op && s->op <= OP_SUB_V) ||
  3013.        (OP_EQ_F <= s->op && s->op <= OP_GT) ||
  3014.        (OP_AND <= s->op && s->op <= OP_BITOR)) {
  3015.     arg1 = DEC_Get(df, s->a, typ1);
  3016.     arg2 = DEC_Get(df, s->b, typ2);
  3017.     arg3 = DEC_Global(s->c, typ3);
  3018.  
  3019.     if (arg3) {
  3020.       DEC_Indent(*indent);
  3021.       fprintf(DEC_ofile, "%s = %s %s %s;\n", arg3, arg1, pr_opcodes[s->op].name, arg2);
  3022.     }
  3023.     else {
  3024.       sprintf(line, "(%s %s %s)", arg1, pr_opcodes[s->op].name, arg2);
  3025.       DEC_Immediate(df, s->c, 1, line);
  3026.     }
  3027.   }
  3028.   else if (OP_LOAD_F <= s->op && s->op <= OP_ADDRESS) {
  3029.     arg1 = DEC_Get(df, s->a, typ1);
  3030.     arg2 = DEC_Get(df, s->b, typ2);
  3031.     arg3 = DEC_Global(s->c, typ3);
  3032.  
  3033.     if (arg3) {
  3034.       DEC_Indent(*indent);
  3035.       fprintf(DEC_ofile, "%s = %s.%s;\n", arg3, arg1, arg2);
  3036.     }
  3037.     else {
  3038.       sprintf(line, "%s.%s", arg1, arg2);
  3039.       DEC_Immediate(df, s->c, 1, line);
  3040.     }
  3041.   }
  3042.   else if (OP_STORE_F <= s->op && s->op <= OP_STORE_FNC) {
  3043.     arg1 = DEC_Get(df, s->a, typ1);
  3044.     arg3 = DEC_Global(s->b, typ2);
  3045.  
  3046.     if (arg3) {
  3047.       DEC_Indent(*indent);
  3048.       fprintf(DEC_ofile, "%s = %s;\n", arg3, arg1);
  3049.     }
  3050.     else {
  3051.       sprintf(line, "%s", arg1);
  3052.       DEC_Immediate(df, s->b, 1, line);
  3053.     }
  3054.   }
  3055.   else if (OP_STOREP_F <= s->op && s->op <= OP_STOREP_FNC) {
  3056.     arg1 = DEC_Get(df, s->a, typ1);
  3057.     arg2 = DEC_Get(df, s->b, typ2);
  3058.  
  3059.     DEC_Indent(*indent);
  3060.     fprintf(DEC_ofile, "%s = %s;\n", arg2, arg1);
  3061.   }
  3062.   else if (OP_NOT_F <= s->op && s->op <= OP_NOT_FNC) {
  3063.     arg1 = DEC_Get(df, s->a, typ1);
  3064.     sprintf(line, "!%s", arg1);
  3065.     DEC_Immediate(df, s->c, 1, line);
  3066.   }
  3067.   else if (OP_CALL0 <= s->op && s->op <= OP_CALL8) {
  3068.     nargs = s->op - OP_CALL0;
  3069.     arg1 = DEC_Get(df, s->a, NULL);
  3070.     sprintf(line, "%s (", arg1);
  3071.     sprintf(fnam, "%s", arg1);
  3072.  
  3073.     for (i = 0; i < nargs; i++) {
  3074.       typ1 = NULL;
  3075.       j = 4 + 3 * i;
  3076.  
  3077.       if (arg1) {
  3078.     tfree(arg1);
  3079.     arg1 = 0;
  3080.       }
  3081.  
  3082.       arg1 = DEC_Get(df, j, typ1);
  3083.       strcat(line, arg1);
  3084.  
  3085. #ifndef DONT_USE_DIRTY_TRICKS
  3086.       if (!strcmp(fnam, "WriteCoord"))
  3087.     if (!strcmp(arg1, "org") || !strcmp(arg1, "trace_endpos") || !strcmp(arg1, "p1") || !strcmp(arg1, "p2") || !strcmp(arg1, "o"))
  3088.       strcat(line, "_x");
  3089. #endif
  3090.       if (i < nargs - 1)
  3091.     strcat(line, ",");
  3092.     }
  3093.     strcat(line, ")");
  3094.     DEC_Immediate(df, 1, 1, line);
  3095.  
  3096.     /*
  3097.      * if ( ( ( (s+1)->a != 1) && ( (s+1)->b != 1) && 
  3098.      * ( (s+2)->a != 1) && ( (s+2)->b != 1) ) || 
  3099.      * ( ((s+1)->op) % 100 == OP_CALL0 ) ) {
  3100.      * DEC_Indent(*indent);
  3101.      * fprintf(DEC_ofile,"%s;\n",line);
  3102.      * }
  3103.      */
  3104.     // this SUCKS!!!!!!!!!!!!!
  3105.     if ((((s + 1)->a != 1) && ((s + 1)->b != 1) &&
  3106.      ((s + 2)->a != 1) && ((s + 2)->b != 1)) ||
  3107.     ((((s + 1)->op) % 100 == OP_CALL0) && ((((s + 2)->a != 1)) || ((s + 2)->b != 1)))) {
  3108.       DEC_Indent(*indent);
  3109.       fprintf(DEC_ofile, "%s;\n", line);
  3110.     }
  3111.   }
  3112.   else if (s->op == OP_IF || s->op == OP_IFNOT) {
  3113.     arg1 = DEC_Get(df, s->a, NULL);
  3114.     arg2 = DEC_Global(s->a, NULL);
  3115.  
  3116.     if (s->op == OP_IFNOT) {
  3117.       if (s->b < 1) {
  3118.     eprintf("Found a negative IFNOT jump.");
  3119.     return;
  3120.       }
  3121.  
  3122.       // get instruction right before the target
  3123.       t = s + s->b - 1;
  3124.       tom = t->op % 100;
  3125.  
  3126.       if (tom != OP_GOTO) {
  3127.     // pure if
  3128.     DEC_Indent(*indent);
  3129.     // fprintf(DEC_ofile,"if ( %s ) { /*1*/\n\n",arg1);
  3130.     fprintf(DEC_ofile, "if ( %s ) {\n\n", arg1);
  3131.     (*indent)++;
  3132.       }
  3133.       else {
  3134.     if (t->a > 0) {
  3135.       // ite
  3136.       DEC_Indent(*indent);
  3137.       // fprintf(DEC_ofile,"if ( %s ) { /*2*/\n\n",arg1);
  3138.       fprintf(DEC_ofile, "if ( %s ) {\n\n", arg1);
  3139.       (*indent)++;
  3140.     }
  3141.     else {
  3142.       /*
  3143.        * if ( ( ((t->a + s->b) == 0) || 
  3144.        * ( (arg2 != NULL) && ((t->a + s->b) == 1) ) ) ) {
  3145.        * // while 
  3146.        * 
  3147.        * DEC_Indent(*indent);
  3148.        * fprintf(DEC_ofile,"while ( %s ) {\n\n",arg1);
  3149.        * (*indent)++;
  3150.        * 
  3151.        * } else {
  3152.        * // pure if 
  3153.        * 
  3154.        * DEC_Indent(*indent);
  3155.        * //fprintf(DEC_ofile,"if ( %s ) { //3\n\n",arg1);
  3156.        * fprintf(DEC_ofile,"if ( %s ) {\n\n",arg1);
  3157.        * (*indent)++;
  3158.        * }
  3159.        * 
  3160.        */
  3161.       if ((t->a + s->b) > 1) {
  3162.         // pure if 
  3163.         DEC_Indent(*indent);
  3164.         //fprintf(DEC_ofile,"if ( %s ) { //3\n\n",arg1);
  3165.         fprintf(DEC_ofile, "if ( %s ) {\n\n", arg1);
  3166.         (*indent)++;
  3167.       }
  3168.       else {
  3169.         dum = 1;
  3170.         for (k = t + (t->a); k < s; k++) {
  3171.           tom = k->op % 100;
  3172.           if (tom == OP_GOTO || tom == OP_IF || tom == OP_IFNOT)
  3173.         dum = 0;
  3174.         }
  3175.         if (dum) {
  3176.           // while 
  3177.           DEC_Indent(*indent);
  3178.           fprintf(DEC_ofile, "while ( %s ) {\n\n", arg1);
  3179.           (*indent)++;
  3180.         }
  3181.         else {
  3182.           // pure if 
  3183.           DEC_Indent(*indent);
  3184.           // fprintf(DEC_ofile,"if ( %s ) { //3\n\n",arg1);
  3185.           fprintf(DEC_ofile, "if ( %s ) {\n\n", arg1);
  3186.           (*indent)++;
  3187.         }
  3188.       }
  3189.     }
  3190.       }
  3191.     }
  3192.     else {
  3193.       // do ... while
  3194.       (*indent)--;
  3195.       fprintf(DEC_ofile, "\n");
  3196.       DEC_Indent(*indent);
  3197.       fprintf(DEC_ofile, "} while ( %s );\n", arg1);
  3198.     }
  3199.   }
  3200.   else if (s->op == OP_GOTO) {
  3201.     if (s->a > 0) {
  3202.       // else
  3203.       (*indent)--;
  3204.       fprintf(DEC_ofile, "\n");
  3205.       DEC_Indent(*indent);
  3206.       fprintf(DEC_ofile, "} else {\n\n");
  3207.       (*indent)++;
  3208.     }
  3209.     else {
  3210.       // while
  3211.       (*indent)--;
  3212.       fprintf(DEC_ofile, "\n");
  3213.       DEC_Indent(*indent);
  3214.       fprintf(DEC_ofile, "}\n");
  3215.     }
  3216.   }
  3217.   else {
  3218.     fprintf(DEC_ofile, "\n/* ERROR: UNKNOWN COMMAND */\n");
  3219.   }
  3220.  
  3221.   oprintf("DEC_DecompileStatement - Current line is \"%s\"\n",line);
  3222.   if (arg1) {
  3223.     tfree(arg1);
  3224.     arg1 = 0;
  3225.   }
  3226.   if (arg2) {
  3227.     tfree(arg2);
  3228.     arg2 = 0;
  3229.   }
  3230.   if (arg3) {
  3231.     tfree(arg3);
  3232.     arg3 = 0;
  3233.   }
  3234.  
  3235.   return;
  3236. }
  3237.  
  3238. void DEC_DecompileFunction(register dfunction_t * df)
  3239. {
  3240.   dstatement_t *ds;
  3241.   int indent;
  3242.  
  3243.   // Initialize
  3244.   DEC_Immediate(df, 0, 0, NULL);
  3245.  
  3246.   indent = 1;
  3247.  
  3248.   ds = statements + df->first_statement;
  3249.   while (1) {
  3250.     DEC_DecompileStatement(df, ds, &indent);
  3251.     if (!ds->op)
  3252.       break;
  3253.     ds++;
  3254.   }
  3255.  
  3256.   if (indent != 1)
  3257.     fprintf(DEC_ofile, "/* ERROR : Indentiation structure corrupt */\n");
  3258. }
  3259.  
  3260. ddef_t *GetField(register char *name)
  3261. {
  3262.   int i;
  3263.   ddef_t *d;
  3264.  
  3265.   for (i = 1; i < numfielddefs; i++) {
  3266.     d = &fields[i];
  3267.  
  3268.     if (!strcmp(strings + d->s_name, name))
  3269.       return d;
  3270.   }
  3271.   return NULL;
  3272. }
  3273.  
  3274. void DEC_Function(register char *name)
  3275. {
  3276.   int i, findex, ps;
  3277.   dstatement_t *ds, *ts;
  3278.   dfunction_t *df;
  3279.   ddef_t *par;
  3280.   char *arg2;
  3281.   unsigned short dom, tom;
  3282.  
  3283.   int j, start, end;
  3284.   dfunction_t *dfpred;
  3285.   ddef_t *ef;
  3286.  
  3287.   static char line[256];
  3288.  
  3289.   dstatement_t *k;
  3290.   int dum;
  3291.  
  3292.   for (i = 1; i < numfunctions; i++)
  3293.     if (!strcmp(name, strings + functions[i].s_name))
  3294.       break;
  3295.   if (i == numfunctions) {
  3296.     eprintf("No function named \"%s\"", name);
  3297.     return;
  3298.   }
  3299.   
  3300.   df = functions + i;
  3301.  
  3302.   findex = i;
  3303.  
  3304.   // Check ''local globals''
  3305.   dfpred = df - 1;
  3306.  
  3307.   for (j = 0, ps = 0; j < dfpred->numparms; j++)
  3308.     ps += dfpred->parm_size[j];
  3309.  
  3310.   start = dfpred->parm_start + dfpred->locals + ps;
  3311.  
  3312.   if (dfpred->first_statement < 0 && df->first_statement > 0)
  3313.     start -= 1;
  3314.  
  3315.   if (start == 0)
  3316.     start = 1;
  3317.  
  3318.   end = df->parm_start;
  3319.  
  3320.   for (j = start; j < end; j++) {
  3321.     par = DEC_GetParameter(j);
  3322.  
  3323.     if (par) {
  3324.       if (par->type & (1 << 15))
  3325.     par->type -= (1 << 15);
  3326.  
  3327.       if (par->type == ev_function) {
  3328.     if (strcmp(strings + par->s_name, "IMMEDIATE"))
  3329.       if (strcmp(strings + par->s_name, name)) {
  3330.         fprintf(DEC_ofile, "%s;\n", DEC_Profiles[DEC_GetFunctionIdxByName(strings + par->s_name)]);
  3331.       }
  3332.       }
  3333.       else if (par->type != ev_pointer)
  3334.     if (strcmp(strings + par->s_name, "IMMEDIATE")) {
  3335.       if (par->type == ev_field) {
  3336.         ef = GetField(strings + par->s_name);
  3337.  
  3338.         if (!ef) {
  3339.           eprintf("Could not locate a field named \"%s\"", strings + par->s_name);
  3340.           return;
  3341.         }
  3342.         
  3343.         if (ef->type == ev_vector)
  3344.           j += 3;
  3345. #ifndef DONT_USE_DIRTY_TRICKS
  3346.         if ((ef->type == ev_function) && !strcmp(strings + ef->s_name, "th_pain")) {
  3347.           fprintf(DEC_ofile, ".void(entity attacker, float damage) th_pain;\n");
  3348.         }
  3349.         else
  3350. #endif
  3351.           fprintf(DEC_ofile, ".%s %s;\n", type_names[ef->type], strings + ef->s_name);
  3352.       }
  3353.       else {
  3354.         if (par->type == ev_vector)
  3355.           j += 2;
  3356.         if (par->type == ev_entity || par->type == ev_void) {
  3357.           fprintf(DEC_ofile, "%s %s;\n", type_names[par->type], strings + par->s_name);
  3358.         }
  3359.         else {
  3360.           line[0] = '\0';
  3361.           sprintf(line, "%s", DEC_ValueString(par->type, &pr_globals[par->ofs]));
  3362.  
  3363.           if ((strlen(strings + par->s_name) > 1) &&
  3364.           isupper((strings + par->s_name)[0]) &&
  3365.           (isupper((strings + par->s_name)[1]) || (strings + par->s_name)[1] == '_')) {
  3366.         fprintf(DEC_ofile, "%s %s    = %s;\n", type_names[par->type], strings + par->s_name, line);
  3367.           }
  3368.           else
  3369.         fprintf(DEC_ofile, "%s %s /* = %s */;\n", type_names[par->type], strings + par->s_name, line);
  3370.         }
  3371.       }
  3372.     }
  3373.     }
  3374.   }
  3375.   // Check ''local globals''
  3376.   if (df->first_statement <= 0) {
  3377.     fprintf(DEC_ofile, "%s", DEC_Profiles[findex]);
  3378.     fprintf(DEC_ofile, " = #%i; \n", -df->first_statement);
  3379.     return;
  3380.   }
  3381.  
  3382.   ds = statements + df->first_statement;
  3383.  
  3384.   while (1) {
  3385.     dom = (ds->op) % 100;
  3386.  
  3387.     if (!dom)
  3388.       break;
  3389.     else if (dom == OP_GOTO) {
  3390.       /*
  3391.        * check for i-t-e 
  3392.        */
  3393.       if (ds->a > 0) {
  3394.     ts = ds + ds->a;
  3395.         /* mark the end of a if/ite construct */
  3396.     ts->op += 100;
  3397.       }
  3398.     }
  3399.     else if (dom == OP_IFNOT) {
  3400.       /*
  3401.        * check for pure if 
  3402.        */
  3403.       ts = ds + ds->b;
  3404.       tom = (ts - 1)->op % 100;
  3405.  
  3406.       if (tom != OP_GOTO)
  3407.         /* mark the end of a if/ite construct */
  3408.     ts->op += 100;
  3409.       else if ((ts - 1)->a < 0) {
  3410.     /*
  3411.      * arg2 = DEC_Global(ds->a,NULL);
  3412.      * 
  3413.      * if (!( ( ((ts-1)->a + ds->b) == 0)   || 
  3414.      * ( (arg2 != NULL) && (((ts-1)->a + ds->b) == 1) ))) 
  3415.      * (ts-1)->op += 100;
  3416.      * 
  3417.      * if (arg2) {
  3418.      *   tfree(arg2);
  3419.      *   arg2 = 0;
  3420.      * }
  3421.      */
  3422.     if (((ts - 1)->a + ds->b) > 1) {
  3423.       // pure if 
  3424.       /* mark the end of a if/ite construct */
  3425.       ts->op += 100;
  3426.     }
  3427.     else {
  3428.       dum = 1;
  3429.       for (k = (ts - 1) + ((ts - 1)->a); k < ds; k++) {
  3430.         tom = k->op % 100;
  3431.         if (tom == OP_GOTO || tom == OP_IF || tom == OP_IFNOT)
  3432.           dum = 0;
  3433.       }
  3434.       if (!dum) {
  3435.         // pure if 
  3436.         /* mark the end of a if/ite construct */
  3437.         ts->op += 100;
  3438.       }
  3439.     }
  3440.       }
  3441.     }
  3442.     else if (dom == OP_IF) {
  3443.       ts = ds + ds->b;
  3444.       /* mark the start of a do construct */
  3445.       ts->op += 10000;
  3446.     }
  3447.     ds++;
  3448.   }
  3449.  
  3450.   // print the prototype
  3451.   fprintf(DEC_ofile, "%s", DEC_Profiles[findex]);
  3452.  
  3453.   // handle state functions
  3454.   ds = statements + df->first_statement;
  3455.  
  3456.   if (ds->op == OP_STATE) {
  3457.     par = DEC_GetParameter(ds->a);
  3458.     if (!par) {
  3459.       eprintf("DEC_Function - Can't determine frame number.");
  3460.       return;
  3461.     }
  3462.  
  3463.     arg2 = DEC_Get(df, ds->b, NULL);
  3464.     if (!arg2) {
  3465.       eprintf("DEC_Function - No state parameter with offset %i.", ds->b);
  3466.       return;
  3467.     }
  3468.  
  3469.     fprintf(DEC_ofile, " = [ %s, %s ]", DEC_ValueString(par->type, &pr_globals[par->ofs]), arg2);
  3470.     tfree(arg2);
  3471.     arg2 = 0;
  3472.   }
  3473.   else {
  3474.     fprintf(DEC_ofile, " =");
  3475.   }
  3476.   fprintf(DEC_ofile, " {\n\n");
  3477.  
  3478. #ifdef    QC_PROFILE
  3479.   fprintf(DEC_profile,"%s",DEC_Profiles[findex]);
  3480.   fprintf(DEC_profile,") %s;\n",name);
  3481. #endif
  3482.  
  3483.   // calculate the parameter size
  3484.   for (j = 0, ps = 0; j < df->numparms; j++)
  3485.     ps += df->parm_size[j];
  3486.  
  3487.   // print the locals
  3488.   if (df->locals > 0) {
  3489.     if ((df->parm_start) + df->locals - 1 >= (df->parm_start) + ps) {
  3490.       for (i = df->parm_start + ps; i < (df->parm_start) + df->locals; i++) {
  3491.     par = DEC_GetParameter(i);
  3492.  
  3493.     if (!par) {
  3494.       fprintf(DEC_ofile, "   /* ERROR: No local name with offset %i */\n", i);
  3495.     }
  3496.     else {
  3497.       if (par->type == ev_function)
  3498.         fprintf(DEC_ofile, "   /* ERROR: Fields and functions must be global */\n");
  3499.       else
  3500.         fprintf(DEC_ofile, "   local %s;\n", DEC_PrintParameter(par));
  3501.       if (par->type == ev_vector)
  3502.         i += 2;
  3503.     }
  3504.       }
  3505.  
  3506.       fprintf(DEC_ofile, "\n");
  3507.     }
  3508.   }
  3509.  
  3510.   // do the hard work
  3511.   DEC_DecompileFunction(df);
  3512.   fprintf(DEC_ofile, "\n};\n");
  3513. }
  3514.  
  3515. bool DEC_DecompileFunctions(register char *destDir)
  3516. {
  3517.   int i;
  3518.   dfunction_t *d;
  3519.   FILE *f;
  3520.   char fname[512];
  3521.  
  3522.   DEC_CalcProfiles();
  3523.  
  3524.   fname[0] = '\0';
  3525.   sprintf(fname, "%s%s", destDir, "progs.src");
  3526.   DEC_progssrc = fopen(fname, "w");
  3527.   if (!DEC_progssrc) {
  3528.     eprintf("DEC_DecompileFunctions - Could not open \"progs.src\" for output.");
  3529.     return FALSE;
  3530.   }
  3531.  
  3532.   fprintf(DEC_progssrc, "./progs.dat\n\n");
  3533.  
  3534. #ifdef    QC_PROFILE
  3535.   DEC_profile  = fopen( "!profile.qc", "w" );
  3536.   if ( !DEC_profile )
  3537.   Error("DEC_DecompileFunctions - Could not open \"!profile.qc\" for output.");
  3538.   fprintf(DEC_progssrc,"!profile.qc\n");
  3539. #endif
  3540.  
  3541.   for (i = 1; i < numfunctions; i++) {
  3542.     d = &functions[i];
  3543.  
  3544.     fname[0] = '\0';
  3545.     sprintf(fname, "%s%s", destDir, strings + d->s_file);
  3546.     f = fopen(fname, "a+");
  3547.  
  3548.     if (!DEC_AlreadySeen(fname))
  3549.       fprintf(DEC_progssrc, "%s\n", fname);
  3550.  
  3551.     if (!f) {
  3552.       eprintf("DEC_DecompileFunctions - Could not open \"%s\" for output.", fname);
  3553.       return FALSE;
  3554.     }
  3555.     DEC_ofile = f;
  3556.     DEC_Function(strings + d->s_name);
  3557.  
  3558.     if (fclose(f)) {
  3559.       eprintf("DEC_DecompileFunctions - Could not close \"%s\" properly.", fname);
  3560.       return FALSE;
  3561.     }
  3562.   }
  3563.  
  3564.   if (fclose(DEC_progssrc)) {
  3565.     eprintf("DEC_DecompileFunctions - Could not close \"progs.src\" properly.");
  3566.     return FALSE;
  3567.   }
  3568.   
  3569. #ifdef    QC_PROFILE
  3570.   if ( fclose(DEC_profile) )
  3571.   Error("DEC_DecompileFunctions - Could not close \"!profile.qc\" properly.");
  3572. #endif
  3573.   return TRUE;
  3574. }
  3575.  
  3576. char *DEC_GlobalStringNoContents(register gofs_t ofs)
  3577. {
  3578.   int i;
  3579.   ddef_t *def;
  3580.   static char line[128];
  3581.  
  3582.   line[0] = '0';
  3583.   sprintf(line, "%i(???)", ofs);
  3584.  
  3585.   for (i = 0; i < numglobaldefs; i++) {
  3586.     def = &globals[i];
  3587.  
  3588.     if (def->ofs == ofs) {
  3589.       line[0] = '0';
  3590.       sprintf(line, "%i(%s)", def->ofs, strings + def->s_name);
  3591.       break;
  3592.     }
  3593.   }
  3594.  
  3595.   i = strlen(line);
  3596.   for (; i < 16; i++)
  3597.     strcat(line, " ");
  3598.   strcat(line, " ");
  3599.  
  3600.   return line;
  3601. }
  3602.  
  3603. char *DEC_GlobalString(register gofs_t ofs)
  3604. {
  3605.   char *s;
  3606.   int i;
  3607.   ddef_t *def;
  3608.   static char line[128];
  3609.  
  3610.   line[0] = '0';
  3611.   sprintf(line, "%i(???)", ofs);
  3612.  
  3613.   for (i = 0; i < numglobaldefs; i++) {
  3614.     def = &globals[i];
  3615.  
  3616.     if (def->ofs == ofs) {
  3617.  
  3618.       line[0] = '0';
  3619.       if (!strcmp(strings + def->s_name, "IMMEDIATE")) {
  3620.     s = PR_ValueString(def->type, &pr_globals[ofs]);
  3621.     sprintf(line, "%i(%s)", def->ofs, s);
  3622.       }
  3623.       else
  3624.     sprintf(line, "%i(%s)", def->ofs, strings + def->s_name);
  3625.     }
  3626.   }
  3627.  
  3628.   i = strlen(line);
  3629.   for (; i < 16; i++)
  3630.     strcat(line, " ");
  3631.   strcat(line, " ");
  3632.  
  3633.   return line;
  3634. }
  3635.  
  3636. /*
  3637.  * fix: same as PR_PrintStatement
  3638.  *  mprintf("%4i : %4i : %s ", (int)(s - statements), statement_linenums[s - statements], pr_opcodes[s->op].opname);
  3639.  */
  3640. void DEC_PrintStatement(register dstatement_t * s)
  3641. {
  3642.   int i;
  3643.  
  3644.   mprintf("%4i : %s ", (int)(s - statements), pr_opcodes[s->op].opname);
  3645.   i = strlen(pr_opcodes[s->op].opname);
  3646.   for (; i < 10; i++)
  3647.     mprintf(" ");
  3648.  
  3649.   if (s->op == OP_IF || s->op == OP_IFNOT)
  3650.     mprintf("%sbranch %i", DEC_GlobalString(s->a), s->b);
  3651.   else if (s->op == OP_GOTO) {
  3652.     mprintf("branch %i", s->a);
  3653.   }
  3654.   else if ((unsigned)(s->op - OP_STORE_F) < 6) {
  3655.     mprintf("%s", DEC_GlobalString(s->a));
  3656.     mprintf("%s", DEC_GlobalStringNoContents(s->b));
  3657.   }
  3658.   else {
  3659.     if (s->a)
  3660.       mprintf("%s", DEC_GlobalString(s->a));
  3661.     if (s->b)
  3662.       mprintf("%s", DEC_GlobalString(s->b));
  3663.     if (s->c)
  3664.       mprintf("%s", DEC_GlobalStringNoContents(s->c));
  3665.   }
  3666.   mprintf("\n");
  3667. }
  3668.  
  3669. /*
  3670.  * fix: same as PrintFunction
  3671.  */
  3672. void DEC_PrintFunction(register char *name)
  3673. {
  3674.   int i;
  3675.   dstatement_t *ds;
  3676.   dfunction_t *df;
  3677.  
  3678.   for (i = 0; i < numfunctions; i++)
  3679.     if (!strcmp(name, strings + functions[i].s_name))
  3680.       break;
  3681.   if (i == numfunctions)
  3682.     eprintf("No function names \"%s\"", name);
  3683.   else {
  3684.     df = functions + i;
  3685.  
  3686.     mprintf("Statements for %s:\n", name);
  3687.     ds = statements + df->first_statement;
  3688.     while (1) {
  3689.       DEC_PrintStatement(ds);
  3690.  
  3691.       if (!ds->op)
  3692.         break;
  3693.  
  3694.       ds++;
  3695.     }
  3696.   }
  3697. }
  3698.  
  3699. //===========================================================================
  3700. //interface
  3701. //===========================================================================
  3702.  
  3703. bool qcc(FILE *srcFile, char *srcDir, operation procOper) {
  3704.   char *srcData, *srcFree = 0;
  3705.   char *srcPart;
  3706.   char fileName[1024];
  3707.   int crc;
  3708.   void *freeIt = 0;
  3709.   bool failure = FALSE;
  3710.  
  3711.   if(InitData() == TRUE) {
  3712.   switch (procOper) {
  3713.     case OP_ADD:
  3714.       strcpy(sourcedir, srcDir);
  3715.       if (!(srcData = srcFree = (char *)GetVoidF(srcFile)))
  3716.         break;
  3717.  
  3718.       if(!(srcData = COM_Parse(srcData))) {
  3719.         eprintf("No destination fileName.\n");
  3720.         tfree(srcFree);
  3721.         srcFree = 0;
  3722.         break;
  3723.       }
  3724.  
  3725.       strcpy(destfile, com_token);
  3726.       mprintf("outputfile: %s\n", destfile);
  3727.  
  3728.       pr_dumpasm = FALSE;
  3729.       PR_BeginCompilation(freeIt = (void *)kmalloc(0x100000), 0x100000);
  3730.  
  3731.       // compile all the files
  3732.       do {
  3733.         if(!(srcData = COM_Parse(srcData)))
  3734.           break;
  3735.  
  3736.         sprintf(fileName, "%s%s", sourcedir, com_token);
  3737.         mprintf("compiling %s\n", fileName);
  3738.         if (!(srcPart = (char *)GetPreProcessed(fileName))) {
  3739.           eprintf("cannot open %s\n", fileName);
  3740.           failure = TRUE;
  3741.           break;
  3742.         }
  3743.  
  3744.         if (!PR_CompileFile(srcPart, fileName)) {
  3745.           eprintf("cannot compile %s\n", fileName);
  3746.           tfree(srcPart);
  3747.           srcPart = 0;
  3748.           failure = TRUE;
  3749.           break;
  3750.         }
  3751.         else {
  3752.           tfree(srcPart);
  3753.           srcPart = 0;
  3754.         }
  3755.  
  3756.       } while (1);
  3757.  
  3758.       if(failure == FALSE) {
  3759.         if (PR_FinishCompilation()) {
  3760.           // write progdefs.h
  3761.           sprintf(fileName, "%s%s", sourcedir, "progdefs.h");
  3762.           // write data file
  3763.           WriteData(PR_WriteProgdefs(fileName));
  3764.           // write files.dat
  3765.           WriteFiles();
  3766.         }
  3767.         else
  3768.           eprintf("compilation errors");
  3769.       }
  3770.       else
  3771.         eprintf("compilation errors");
  3772.  
  3773.       tfree(srcFree);
  3774.       srcFree = 0;
  3775.       break;
  3776.     default:
  3777.       break;
  3778.   }
  3779.     ExitData();
  3780.     return TRUE;
  3781.   }
  3782.   else
  3783.     return FALSE;
  3784. }
  3785.  
  3786. bool unqcc(FILE *srcFile, char *destDir, operation procOper) {
  3787.   bool retval = FALSE;
  3788.  
  3789.   switch (procOper) {
  3790.     case OP_EXTRACT:
  3791.       if(ReadData(srcFile) == TRUE) {
  3792.         CreatePath(destDir);
  3793.         retval = DEC_DecompileFunctions(destDir);
  3794.       }
  3795.       else
  3796.         eprintf("decompilation error!\n");
  3797.       break;
  3798.     case OP_LIST:
  3799.     default:
  3800.       retval = ShowData(srcFile);
  3801.       break;
  3802.   }
  3803.   
  3804.   ExitData();
  3805.   return retval;
  3806. }
  3807.  
  3808.